APU period table: Difference between revisions
From NESdev Wiki
Jump to navigationJump to search
(and if you have no python...) |
(moved the program below the output because most people are looking for something to CNP; added link to Celius' tables with more explanation) |
||
Line 2: | Line 2: | ||
But some people might not know the [[wikipedia:piano key frequencies|piano key frequencies]] or how to convert them to periods for the NES. | But some people might not know the [[wikipedia:piano key frequencies|piano key frequencies]] or how to convert them to periods for the NES. | ||
Fortunately, this has been done for you. | Fortunately, this has been done for you. | ||
This Python program | |||
== Lookup table == | |||
Here's a lookup table from note numbers (low A = 0) to the values to write to the pulse and triangle period registers. | |||
Triangle notes will sound one octave lower. | |||
<pre> | |||
; NTSC period table generated by mktables.py | |||
.export periodTableLo, periodTableHi | |||
.segment "RODATA" | |||
periodTableLo: | |||
.byt $f1,$7f,$13,$ad,$4d,$f3,$9d,$4c,$00,$b8,$74,$34 | |||
.byt $f8,$bf,$89,$56,$26,$f9,$ce,$a6,$80,$5c,$3a,$1a | |||
.byt $fb,$df,$c4,$ab,$93,$7c,$67,$52,$3f,$2d,$1c,$0c | |||
.byt $fd,$ef,$e1,$d5,$c9,$bd,$b3,$a9,$9f,$96,$8e,$86 | |||
.byt $7e,$77,$70,$6a,$64,$5e,$59,$54,$4f,$4b,$46,$42 | |||
.byt $3f,$3b,$38,$34,$31,$2f,$2c,$29,$27,$25,$23,$21 | |||
.byt $1f,$1d,$1b,$1a,$18,$17,$15,$14 | |||
periodTableHi: | |||
.byt $07,$07,$07,$06,$06,$05,$05,$05,$05,$04,$04,$04 | |||
.byt $03,$03,$03,$03,$03,$02,$02,$02,$02,$02,$02,$02 | |||
.byt $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01 | |||
.byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 | |||
.byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 | |||
.byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 | |||
.byt $00,$00,$00,$00,$00,$00,$00,$00 | |||
</pre> | |||
== Table generator == | |||
This Python program generated the above lookup table. | |||
You can use it to make a table for PAL, or you can adjust it for other [[wikipedia:musical tuning]] systems: | |||
<pre> | <pre> | ||
#!/usr/bin/env python | #!/usr/bin/env python | ||
Line 69: | Line 97: | ||
</pre> | </pre> | ||
== | == See also == | ||
*[http://www.freewebs.com/the_bott/NotesTableNTSC.txt Celius' NTSC table] | |||
*[http://www.freewebs.com/the_bott/NotesTablePAL.txt Celius' PAL table] | |||
. | |||
. | |||
Revision as of 23:44, 3 April 2010
APU Pulse and APU Triangle use "period" values to set the pitch of the note. But some people might not know the piano key frequencies or how to convert them to periods for the NES. Fortunately, this has been done for you.
Lookup table
Here's a lookup table from note numbers (low A = 0) to the values to write to the pulse and triangle period registers. Triangle notes will sound one octave lower.
; NTSC period table generated by mktables.py .export periodTableLo, periodTableHi .segment "RODATA" periodTableLo: .byt $f1,$7f,$13,$ad,$4d,$f3,$9d,$4c,$00,$b8,$74,$34 .byt $f8,$bf,$89,$56,$26,$f9,$ce,$a6,$80,$5c,$3a,$1a .byt $fb,$df,$c4,$ab,$93,$7c,$67,$52,$3f,$2d,$1c,$0c .byt $fd,$ef,$e1,$d5,$c9,$bd,$b3,$a9,$9f,$96,$8e,$86 .byt $7e,$77,$70,$6a,$64,$5e,$59,$54,$4f,$4b,$46,$42 .byt $3f,$3b,$38,$34,$31,$2f,$2c,$29,$27,$25,$23,$21 .byt $1f,$1d,$1b,$1a,$18,$17,$15,$14 periodTableHi: .byt $07,$07,$07,$06,$06,$05,$05,$05,$05,$04,$04,$04 .byt $03,$03,$03,$03,$03,$02,$02,$02,$02,$02,$02,$02 .byt $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01 .byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 .byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 .byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 .byt $00,$00,$00,$00,$00,$00,$00,$00
Table generator
This Python program generated the above lookup table. You can use it to make a table for PAL, or you can adjust it for other wikipedia:musical tuning systems:
#!/usr/bin/env python # # Lookup table generator for note periods # Copyright 2010 Damian Yerrick # # Copying and distribution of this file, with or without # modification, are permitted in any medium without royalty # provided the copyright notice and this notice are preserved. # This file is offered as-is, without any warranty. # from __future__ import with_statement, division import sys ntscOctaveBase = 39375000.0/(22 * 16 * 55) palOctaveBase = 266017125.0/(10 * 16 * 16 * 55) maxNote = 80 def makePeriodTable(filename, pal=False): semitone = 2.0**(1./12) octaveBase = palOctaveBase if pal else ntscOctaveBase relFreqs = [(1 << (i // 12)) * semitone**(i % 12) for i in xrange(maxNote)] periods = [int(round(octaveBase / freq)) - 1 for freq in relFreqs] systemName = "PAL" if pal else "NTSC" with open(filename, 'wt') as outfp: outfp.write("""; %s period table generated by mktables.py .export periodTableLo, periodTableHi .segment "RODATA" periodTableLo:\n""" % systemName) for i in range(0, maxNote, 12): outfp.write(' .byt ' + ','.join('$%02x' % (i % 256) for i in periods[i:i + 12]) + '\n') outfp.write('periodTableHi:\n') for i in range(0, maxNote, 12): outfp.write(' .byt ' + ','.join('$%02x' % (i >> 8) for i in periods[i:i + 12]) + '\n') def makePALPeriodTable(filename): return makePeriodTable(filename, pal=True) tableNames = { 'period': makePeriodTable, 'palperiod': makePALPeriodTable } def main(argv): if len(argv) >= 2 and argv[1] in ('/?', '-?', '-h', '--help'): print "usage: %s TABLENAME FILENAME" % argv[0] print "known tables:", ' '.join(sorted(tableNames)) elif len(argv) < 3: print "mktables: too few arguments; try %s --help" % argv[0] elif argv[1] in tableNames: tableNames[argv[1]](argv[2]) else: print "mktables: no such table %s; try %s --help" % (argv[1], argv[0]) if __name__=='__main__': main(sys.argv)