My POKEY note table - Forum Atarum

Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

  • :
  • :

Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

    I have made a POKEY note table in .xls format

    The table has these settings:

    $Ax (square wave) for 64 khz, 15 khz, and 16-bit
    $Cx (saw wave) for 64 khz, 1.79 mhz, 16-bit, includes RMT C and E settings
    $2x (triangle wave) for 64 khz, 1.79 mhz, and 16-bit
    $8x plus 9-bit for 1.79 mhz and 16-bit
    $4x for 1.79 mhz and 16-bit, there are two tables, one of them is a mod 3 table, uses multiples of three like $Cx

    Also has reverse 16-bit settings. You set 16-bit mode, play first channel and make second channel silent.

    $Ax - uses 64khz clock. Standard $Ax table, then 50% duty cycle NES wave starting at A#3 and going down to C2

    $8x - 1.79 mhz clock. Distorted guitars. Two note tables, plus a third table with vibrating sounds.

    $4x - 1.79 mhz clock. Distorted guitars. Three note tables, plus a third table with vibrating sounds.

    It's in English, maybe someone can translate to Polish?

    Still not finished, I will add SKCTL=$8B and hi-pass AUDCTL=$02, $04, $06 settings.
    • 2:
    • CommentTime21 Apr 2020 zmieniony
    Thanks for this!
    When you finish, somebody would translate, not sooner (additional work). If nobody else, then me.
    I think a good idea is to place this on
    Good idea.

    I am also trying to learn Polish ... it's very hard lol. :) Maybe by the time the note table is finished.

    I hope a new tracker will come of this work. Meanwhile, my $4x reverse 16-bit table has been hacked into RMT on the AtariAge forum. Might be useful, maybe, for now.
    • 4: CommentAuthorpirx
    • CommentTime21 Apr 2020
    is it working the same for PAL and NTSC machines?
    Not sure. I tested everything in NTSC and tuned by ear against the standard $Ax table.
    Here are RMT hacked with reverse $4x table into 6 distortion. You place notes in first column. Not sure if the hack is working or not. R0ger did the hacks.
    • 7:
    • CommentTime21 Apr 2020


    It's in English, maybe someone can translate to Polish?

    Sure, we can do it.
    It's a long way from being done. $4x reverse 16 took me two months to do. I had to listen to all 65,536 frequencies.
    • 9:
    • CommentTime21 Apr 2020
    Wow! Incredible hard work.
    I also did work on $4x 1.79 mhz plus SKCTL=$8B two tone. Distorted guitars, plus the two $Cx note tables, but they are run through a fuzzy distortion. Very close to finishing that one.
    Added a new update ... SKCTL two tone mode for $Ax distortions ...


    More work remains
    I have started on a new note table setting.

    AUDCTL=$64 (1.79 on 0 and 2 channel, plus hi pass filter on 2 and 0)


    Using $2x distortion, placing different frequencies in AUDF0 and AUDF2 to make distorted guitar sounds. These sound sharp, and I think I can get a greater range than with other settings. Sounds promising!

    Now to step through 65,536 frequencies ...
    • 13:
    • CommentTime9 Jul 2020 zmieniony
    Maybe I do not understand, but I have read in xls:

    "15 khz tables are identical to 64 khz tables but transposed down 2 octaves."

    In my opinion that's not true. the 15khz clock is not taken from 64khz/4.
    "For timers using the 15KHz or 64KHz clock, the period is N+1 ticks, where each tick is 114 cycles with the 15KHz clock and 28 cycles with the 64KHz clock"

    So (4*28=112)!=114 and I remember that it lead to quiet audible frequency drift.
    That may be accurate. 15 khz mode for me seems to work very well in the lower frequencies using the standard 64 khz table, it gets a little out of tune in the higher ranges, especially around C4.
    • 15: CommentAuthorilmenit
    • CommentTime15 Jul 2020
    It's great work. I'm thinking if this could be somehow automated with some sound tuning tool, instead of listening.
    I agree. My ears tend to bleed after awhile. :)

    Working on another 65,536 frequencies for another setting. This time, it's $2x on channel 0, 1.79 mhz on 0 and 2, and hi pass filter. Distorted guitars but with a higher tuning range.
    I will also add, the 16 bit tables on $Cx (both iterations), $2x, $4x (both iterations), and also the 1.79 mhz tables on $Cx and $2x, all were tuned by ear using the $Ax 8-bit and 16-bit settings as an audio reference. It might work better if we had a means of checking these with a tool, maybe.
    • 18: CommentAuthorpirx
    • CommentTime31 Jul 2020 zmieniony
    Hi, maybe use some tool to decode frequencies?
    Tried to play a bit with aubio library and wav recorded from apokeysnd.dll, the result table enclosed (out.csv)
    The sounds were only 1 frame long, so the lowest frequency decoded was 50Hz.
    This is for plain vanilla DSOUND like turbo basic stuff.

    Generation (thanks to antrykot, win32 python):
    from ctypes import *
    from array import array
    import wave

    pokey = CDLL(r'...\path_to\apokeysnd.dll')

    def sound(chn, n, gen, amp):
    pokey.APokeySound_PutByte(c_int(chn * 2), c_int(n))
    pokey.APokeySound_PutByte(c_int(chn * 2 + 1), c_int(gen * 16 + amp))
    pokey.APokeySound_PutByte(c_int(8), c_int(0))

    def dsound(chn, n, gen, amp):
    pokey.APokeySound_PutByte(c_int(chn * 2), c_int(n%256))
    pokey.APokeySound_PutByte(c_int((chn+1) * 2), c_int(n//256))
    pokey.APokeySound_PutByte(c_int((chn+1) * 2 + 1), c_int(gen * 16 + amp))
    pokey.APokeySound_PutByte(c_int(8), c_int(0b00011000))

    out ='pokey.wav', 'wb')
    buf = (c_ubyte * 8192)()

    def wait(n):
    for i in range(n):
    size = pokey.APokeySound_Generate(114 * 312, buf, c_int(16))
    out.writeframes(array('B', buf[0:size]))

    for i in range(0,0x10000//40,1):
    dsound(0, i, 10, 15)

    Pitch detection:
    import aubio
    import numpy as np

    buf_s = int(44100*2/50)
    hop_s = int(44100*2/50)
    src = aubio.source('pokey.wav', hop_size=hop_s)
    print(src.uri, src.samplerate, src.channels, src.duration)
    samplerate = src.samplerate
    tolerance = 0.8
    pitch_o = aubio.pitch("yin", buf_s, hop_s, samplerate)

    total_frames = 0
    while True:
    samples, read = src()
    pitch = pitch_o(samples)[0]
    confidence = pitch_o.get_confidence()
    total_frames += read
    print (pitch, aubio.freq2note(pitch))
    if read < hop_s: break
    • 19: CommentAuthorpirx
    • CommentTime31 Jul 2020
    You could sample the true atari output to .wav file and decode frequencies using a similar method.
    Thanks for this! I think for now I am still going to rely on my ears ... once this is finished though, you all can maybe double check it all and see how it matches up. Some of these new settings are going to need new formulas.

    Meanwhile: I have learned how to convert my music into SAP, so I am going to start putting them onto ASMA. These are my first four contributions ... all using experimental SKCTL=$8B settings.

    Most SAP players won't do these, but I think they will work on the real Atari hardware. Please test ...
    • 21:
    • CommentTime1 Aug 2020
    IMHO (W)ASAP should support two-tone mode but apperently it doesn't work. Or is it?
    I found the problem.

    It is that WASAP doesn't like VBI being called, as I have done in my code. Apparently these are better suited to SAP-B, so I am trying to investigate how to modify these for SAP-B, it seems I need a timer in the code, something that uses VCOUNT. I am still trying to figure it out. :) Fairly new at this, sorry.
    • 23:
    • CommentTime2 Aug 2020 zmieniony
    For SAP TYPE-B there should be piece of code which you call every frame (or mutliples times a frame), and it should end with RTS. So that "throughway" one.
    I can confirm two tone mode $Ax distortion
    works in WASAP. Piotr helped me with converting two of mine into SAP-B. The Mario and Worldrunner ones, which both use $Ax plus SKCTL. I am going to try the Donkey Kong Country one next, that uses $4x distortion plus SKCTL for the guitars.
    • 25: CommentAuthorilmenit
    • CommentTime3 Aug 2020
    @pirx, super!
    My first two:

    Tempo on these is wrong, because I used NTSC duration, not PAL. They need to be fixed to play at right speed.

    Mario World Overworld: This one uses $Ax square @1.79 two-tone SKCTL mode. Play channel 0, silent channel 1. This is the famous "Save to Cassette" bell sound. :)

    3D Worldrunner: $Ax square @64 khz SKCTL for channel 0, channel 1 silent. Second channel has the melody, then you play first channel a fixed number of semitones above the first channel, to maintain pulse width.

    Tried on WASAP and it works. :)

    Going to try converting more ...
    • 27:
    • CommentTime4 Aug 2020 zmieniony
    OK, fixed timing for these two. TBH 3D Worldrunner works a bit better, Mario "knocks" sometimes instead of playing sound.
    Please check to see if the SKIPWRITEZERO code in Worldrunner is also in Mario. I may have forgotten to include it. There is some popping in the silent second channel also.
    Did another one ... it seems to work in Altirra. Also works in WASAP.

    This uses $4x distortion @1.79 mhz, in SKCTL mode. Again the timing is wrong (NTSC) ...

    I also fixed the note rests on the third channel. $0B makes silence on $Cx @1.79 mhz, not $0E

    How is the best way to correct the timings on it so that it plays at the right tempo?

    Also, noises and pops occur on the silent second channel. Is there a fix for this?
    I actually cleaned these up!

    Somebody on Atariage suggested this change and it worked!


    These should also be applied to worldrunner and mario as well. It kills the popping sound.

    Also: There are audible high frequencies on worldrunner and mario. These are all in third channel,$Cx @1.79mhz. All 14's in the duration table need to be changed to 11's, as these will make silence instead of high frequency noise.
    Mario World 1 and Worldrunner now updated, no pops. :) Also fixed the high frequencies. Good work ...
    And also this:

    Area 1/Area 3 theme from Zanac. This time, I used $Ax SKCTL with AUDCTL=$00, but I allow second channel to play on top of the first instead of silencing it. This transposes the melody down an octave and makes it into a 25% NES Pulse Wave. This method may make other interesting effects in other SKCTL settings.
    • 33:
    • CommentTime5 Aug 2020
    Great. If you want to change the timing into NTSC yourself just change "TYBE B" into the following sequence:
    TYPE B
    FASTPLAY 262
    Great! This helps alot ... :)
    OK, this is where I need help.

    I am attaching .xex and .asm sources.

    In this music, I am using SKCTL, these settings:

    AUDCTL=$20 (1.79 on third channel)

    0 - $Ax (SKCTL Two tone)
    1 - silent
    2 - $2x (1.79 mhz channel - triangle)
    3 - $Ax (standard square wave)

    The problem comes when I try to do note rests by using zero frequency. On $Ax channels this is no problem, 0 frequency cannot be heard by human ears, but in $2x, you can hear it. This also happens in $Ax at 15 khz mode as well.

    What is needed is code modification so that all zero's in the frequency table automatically get silenced. Does anybody have any ideas? Thanks ...
    Updated note table:

    Corrected the 15 khz settings on page 1 and page 4 of this .xls (thanks, jhusak!) with the proper frequency values. Again, calibrated to NTSC, the PAL ones should not be hard to calculate.

    There's still a couple of documentation errors on $4x distortions at 1.79 mhz, but will fix this with the next update. Also still working out some tables for hi-pass mode, and the $4x SKCTL mode.
    I have also sorted out the zero frequency problems on distortion $2x ... will post updated code soon as I can ... been real busy at work. :)
    The other interesting experiment is with $Cx mod 3 smooth bass settings in 16-bit. I believe pavros came up with a method to stabilize these tones by using 3rd pokey channel and resetting polycounters, but this is for standard 8-bit AUDCTL=$00.

    For 16 bit, because third channel usage is impossible, one will have to use frequencies divisible by 6 for one waveform, and frequencies divisible by 3 but not 6, for the other one. This is combined with the polycounter reset before each note play. I will experiment and modify the note table accordingly.
    Dzięki. Każda metoda byłaby pomocna.

    I am still going through the course on Duolingo and I am having a hard time keeping vocabulary. I have some of the grammar down but can't remember my noun cases well (like this: Woda jest fajna. Piję wodę. Jestem wodą. Idź do wody.) I had to use the translator to get the endings for woda. :) Hard to remember these ...

    I did Swedish on duolingo and I am about A2 on it now. But Swedish is easy for English speakers. My Spanish is about the same too. But Polish is important!
    • 40: CommentAuthorpirx
    • CommentTime30 Aug 2020
    English is my native language. I have some familiarity with latin and germanic languages, so it may help some. My main difficulty is in remembering vocabulary, and the case endings. I will keep trying.
    I had a question about my .s code I use to make the tunes. I want to make it so that it can play stereo POKEY, 8 channels. I know I have to put in extra equates, but looking for some help as to how to address those extra channels in my code ... that is, $04 to $07 in CHANNLTBL to get the extra sound channels.