Converting NES Tunes from NTSC to PAL?

Discuss NSF files, FamiTracker, MML tools, or anything else related to NES music.
SMB2J-2Q
Posts: 271
Joined: Thu Jul 27, 2017 5:13 pm

Converting NES Tunes from NTSC to PAL?

Post by SMB2J-2Q »

I am wondering the proper way to convert any NES-related chiptune from NTSC to PAL?

For example, the music in the PAL version of Super Mario Bros. was not properly optimized in this conversion. While most of the background music was indeed changed in tempo, the Princess saved music sounds awfully slower in this regard.
https://www.youtube.com/watch?v=APe83KBXf9M&t=41m45s

I am wondering if it may be possible to do an NTSC-to-PAL speed-up by multiplying the note values in each song data by 1.042709376 or 0.8333 to raise the pitch up?

Here's how the PAL version's music was affected:

Code: Select all

FreqRegLookupTbl: ;PAL diff: Different frequencies to accomodate clock speed differences
      .byte $00, $88, $00, $2b, $00, $00
      .byte $02, $72, $02, $4f, $02, $2e, $02, $0e
      .byte $01, $f1, $01, $ba, $01, $a1, $01, $8a
      .byte $01, $74, $01, $5F, $01, $4B, $01, $39
      .byte $01, $27, $01, $17, $01, $07, $00, $F8
      .byte $00, $EA, $00, $DD, $00, $D1, $00, $C5
      .byte $00, $BA, $00, $AF, $00, $A5, $00, $9C
      .byte $00, $94, $00, $8B, $00, $83, $00, $7C
      .byte $00, $6E, $00, $74, $00, $68, $00, $4E
      .byte $00, $5C, $00, $58, $00, $52, $00, $4A
      .byte $00, $42, $00, $3E, $00, $36, $00, $31
      .byte $00, $27, $00, $20, $04, $1D, $03, $15
      .byte $02, $BE, $02, $98, $01, $D5, $00, $62

MusicLengthLookupTbl: ;PAL diff: Different lengths to accomodate speed differences
      .byte $04, $08, $10, $20, $40, $18, $30, $0C
      .byte $03, $06, $0C, $18, $30, $12, $24, $08
      .byte $03, $06, $0C, $18, $30, $12, $24, $08
      .byte $24, $02, $06, $04, $0C, $12, $18, $08
      .byte $1B, $01, $05, $03, $09, $0D, $12, $06
      .byte $12, $01, $03, $02, $06, $09, $0C, $04
And how it was for us (the NTSC version):

Code: Select all

FreqRegLookupTbl:
      .db $00, $88, $00, $2f, $00, $00
      .db $02, $a6, $02, $80, $02, $5c, $02, $3a
      .db $02, $1a, $01, $df, $01, $c4, $01, $ab
      .db $01, $93, $01, $7c, $01, $67, $01, $53
      .db $01, $40, $01, $2e, $01, $1d, $01, $0d
      .db $00, $fe, $00, $ef, $00, $e2, $00, $d5
      .db $00, $c9, $00, $be, $00, $b3, $00, $a9
      .db $00, $a0, $00, $97, $00, $8e, $00, $86
      .db $00, $77, $00, $7e, $00, $71, $00, $54
      .db $00, $64, $00, $5f, $00, $59, $00, $50
      .db $00, $47, $00, $43, $00, $3b, $00, $35
      .db $00, $2a, $00, $23, $04, $75, $03, $57
      .db $02, $f9, $02, $cf, $01, $fc, $00, $6a

MusicLengthLookupTbl:
      .db $05, $0a, $14, $28, $50, $1e, $3c, $02
      .db $04, $08, $10, $20, $40, $18, $30, $0c
      .db $03, $06, $0c, $18, $30, $12, $24, $08
      .db $36, $03, $09, $06, $12, $1b, $24, $0c
      .db $24, $02, $06, $04, $0c, $12, $18, $08
      .db $12, $01, $03, $02, $06, $09, $0c, $04
~Ben
Bavi_H
Posts: 250
Joined: Sun Mar 03, 2013 1:52 am
Location: Texas, USA

Re: Converting NES Tunes from NTSC to PAL?

Post by Bavi_H »

PAL needs different period values from NTSC to achieve the same pitch.
PAL needs different duration values in frames from NTSC to achieve the same tempo.[1]

The conversion formulas are
period_value_pal = (period_value_ntsc + 1) × (cpu_frequency_pal / cpu_frequency_ntsc) - 1

duration_value_pal = duration_value_ntsc × (frame_rate_pal / frame_rate_ntsc)
where
(cpu_frequency_pal / cpu_frequency_ntsc) is 0.9289... or exactly 7803169/8400000.

(frame_rate_pal / frame_rate_ntsc) is 0.832079... or exactly 42251322619/50778000000.[2]

When I use these conversion formulas, I get the results below. After applying the change, if I listen to the music in the first level, the tempo is much closer to the NTSC version, but there are audible slips in the tempo and sometimes the channels slip slightly out of sync. I think this is because the conversion has to round the durations to the nearest whole number of frames. If instead you use frame duration values that are exact multiples of the smallest possible durations, then the tempo choices are limited.

Code: Select all

In the PAL version of Super Mario Bros. (PRG+CHR CRC32 9A2DB086),
go to NES file offset 7F10 and replace with:

00 7E 00 2C 00 00 02 76 02 52 02 31 02 11 01 F4
01 BD 01 A4 01 8D 01 76 01 61 01 4D 01 3B 01 29
01 18 01 09 00 FA 00 EC 00 DE 00 D2 00 C6 00 BB
00 B0 00 A6 00 9D 00 95 00 8C 00 84 00 7C 00 6E
00 75 00 69 00 4E 00 5D 00 58 00 53 00 4A 00 42
00 3E 00 37 00 31 00 27 00 20 04 24 03 1A 02 C3
02 9C 01 D8 00 62 04 08 11 21 43 19 32 02 03 07
0D 1B 35 14 28 0A 02 05 0A 14 28 0F 1E 07 2D 02
07 05 0F 16 1E 0A 1E 02 05 03 0A 0F 14 07 0F 01
02 02 05 07 0A 03

____________________

A: NTSC period values (hex)
B: NTSC period values (decimal)
C: conversion to PAL period values (decimal)
D: conversion to PAL period values (hex)

A	B	C	D
0088	136	126	007e
002f	47	44	002c
0000	0	0	0000
02a6	678	630	0276
0280	640	594	0252
025c	604	561	0231
023a	570	529	0211
021a	538	500	01f4
01df	479	445	01bd
01c4	452	420	01a4
01ab	427	397	018d
0193	403	374	0176
017c	380	353	0161
0167	359	333	014d
0153	339	315	013b
0140	320	297	0129
012e	302	280	0118
011d	285	265	0109
010d	269	250	00fa
00fe	254	236	00ec
00ef	239	222	00de
00e2	226	210	00d2
00d5	213	198	00c6
00c9	201	187	00bb
00be	190	176	00b0
00b3	179	166	00a6
00a9	169	157	009d
00a0	160	149	0095
0097	151	140	008c
008e	142	132	0084
0086	134	124	007c
0077	119	110	006e
007e	126	117	0075
0071	113	105	0069
0054	84	78	004e
0064	100	93	005d
005f	95	88	0058
0059	89	83	0053
0050	80	74	004a
0047	71	66	0042
0043	67	62	003e
003b	59	55	0037
0035	53	49	0031
002a	42	39	0027
0023	35	32	0020
0475	1141	1060	0424
0357	855	794	031a
02f9	761	707	02c3
02cf	719	668	029c
01fc	508	472	01d8
006a	106	98	0062

____________________

A: NTSC duration values (hex)
B: NTSC duration values (decimal)
C: conversion to PAL duration values (decimal)
D: conversion to PAL duration values (hex)

A	B	C	D
05	5	4	04
0a	10	8	08
14	20	17	11
28	40	33	21
50	80	67	43
1e	30	25	19
3c	60	50	32
02	2	2	02
04	4	3	03
08	8	7	07
10	16	13	0d
20	32	27	1b
40	64	53	35
18	24	20	14
30	48	40	28
0c	12	10	0a
03	3	2	02
06	6	5	05
0c	12	10	0a
18	24	20	14
30	48	40	28
12	18	15	0f
24	36	30	1e
08	8	7	07
36	54	45	2d
03	3	2	02
09	9	7	07
06	6	5	05
12	18	15	0f
1b	27	22	16
24	36	30	1e
0c	12	10	0a
24	36	30	1e
02	2	2	02
06	6	5	05
04	4	3	03
0c	12	10	0a
12	18	15	0f
18	24	20	14
08	8	7	07
12	18	15	0f
01	1	1	01
03	3	2	02
02	2	2	02
06	6	5	05
09	9	7	07
0c	12	10	0a
04	4	3	03

See also

________
[1] adapted from Nesdev Wiki Detect TV system - What to change
[2] CPU frequencies and frame rates for NTSC and PAL were derived from Nesdev Wiki Cycle reference chart
Guest34546

Re: Converting NES Tunes from NTSC to PAL?

Post by Guest34546 »

Also take into account Hybrid region, as well as other audio differences between models such as duty cycle swapping.
SMB2J-2Q
Posts: 271
Joined: Thu Jul 27, 2017 5:13 pm

Re: Converting NES Tunes from NTSC to PAL?

Post by SMB2J-2Q »

Bavi_H wrote: Mon Apr 10, 2023 8:03 pm PAL needs different period values from NTSC to achieve the same pitch.
PAL needs different duration values in frames from NTSC to achieve the same tempo.[1]

The conversion formulas are
period_value_pal = (period_value_ntsc + 1) × (cpu_frequency_pal / cpu_frequency_ntsc) - 1

duration_value_pal = duration_value_ntsc × (frame_rate_pal / frame_rate_ntsc)
where
(cpu_frequency_pal / cpu_frequency_ntsc) is 0.9289... or exactly 7803169/8400000.

(frame_rate_pal / frame_rate_ntsc) is 0.832079... or exactly 42251322619/50778000000.[2]

When I use these conversion formulas, I get the results below. After applying the change, if I listen to the music in the first level, the tempo is much closer to the NTSC version, but there are audible slips in the tempo and sometimes the channels slip slightly out of sync. I think this is because the conversion has to round the durations to the nearest whole number of frames. If instead you use frame duration values that are exact multiples of the smallest possible durations, then the tempo choices are limited.

Code: Select all

In the PAL version of Super Mario Bros. (PRG+CHR CRC32 9A2DB086),
go to NES file offset 7F10 and replace with:

00 7E 00 2C 00 00 02 76 02 52 02 31 02 11 01 F4
01 BD 01 A4 01 8D 01 76 01 61 01 4D 01 3B 01 29
01 18 01 09 00 FA 00 EC 00 DE 00 D2 00 C6 00 BB
00 B0 00 A6 00 9D 00 95 00 8C 00 84 00 7C 00 6E
00 75 00 69 00 4E 00 5D 00 58 00 53 00 4A 00 42
00 3E 00 37 00 31 00 27 00 20 04 24 03 1A 02 C3
02 9C 01 D8 00 62 04 08 11 21 43 19 32 02 03 07
0D 1B 35 14 28 0A 02 05 0A 14 28 0F 1E 07 2D 02
07 05 0F 16 1E 0A 1E 02 05 03 0A 0F 14 07 0F 01
02 02 05 07 0A 03

____________________

A: NTSC period values (hex)
B: NTSC period values (decimal)
C: conversion to PAL period values (decimal)
D: conversion to PAL period values (hex)

A	B	C	D
0088	136	126	007e
002f	47	44	002c
0000	0	0	0000
02a6	678	630	0276
0280	640	594	0252
025c	604	561	0231
023a	570	529	0211
021a	538	500	01f4
01df	479	445	01bd
01c4	452	420	01a4
01ab	427	397	018d
0193	403	374	0176
017c	380	353	0161
0167	359	333	014d
0153	339	315	013b
0140	320	297	0129
012e	302	280	0118
011d	285	265	0109
010d	269	250	00fa
00fe	254	236	00ec
00ef	239	222	00de
00e2	226	210	00d2
00d5	213	198	00c6
00c9	201	187	00bb
00be	190	176	00b0
00b3	179	166	00a6
00a9	169	157	009d
00a0	160	149	0095
0097	151	140	008c
008e	142	132	0084
0086	134	124	007c
0077	119	110	006e
007e	126	117	0075
0071	113	105	0069
0054	84	78	004e
0064	100	93	005d
005f	95	88	0058
0059	89	83	0053
0050	80	74	004a
0047	71	66	0042
0043	67	62	003e
003b	59	55	0037
0035	53	49	0031
002a	42	39	0027
0023	35	32	0020
0475	1141	1060	0424
0357	855	794	031a
02f9	761	707	02c3
02cf	719	668	029c
01fc	508	472	01d8
006a	106	98	0062

____________________

A: NTSC duration values (hex)
B: NTSC duration values (decimal)
C: conversion to PAL duration values (decimal)
D: conversion to PAL duration values (hex)

A	B	C	D
05	5	4	04
0a	10	8	08
14	20	17	11
28	40	33	21
50	80	67	43
1e	30	25	19
3c	60	50	32
02	2	2	02
04	4	3	03
08	8	7	07
10	16	13	0d
20	32	27	1b
40	64	53	35
18	24	20	14
30	48	40	28
0c	12	10	0a
03	3	2	02
06	6	5	05
0c	12	10	0a
18	24	20	14
30	48	40	28
12	18	15	0f
24	36	30	1e
08	8	7	07
36	54	45	2d
03	3	2	02
09	9	7	07
06	6	5	05
12	18	15	0f
1b	27	22	16
24	36	30	1e
0c	12	10	0a
24	36	30	1e
02	2	2	02
06	6	5	05
04	4	3	03
0c	12	10	0a
12	18	15	0f
18	24	20	14
08	8	7	07
12	18	15	0f
01	1	1	01
03	3	2	02
02	2	2	02
06	6	5	05
09	9	7	07
0c	12	10	0a
04	4	3	03

See also

________
[1] adapted from Nesdev Wiki Detect TV system - What to change
[2] CPU frequencies and frame rates for NTSC and PAL were derived from Nesdev Wiki Cycle reference chart
Yes, those two Github pages were what I pasted these bits of code from.

The other thing I wanted to ask was this: how would I add a region auto-detect check, which is what happens already with PAL region titles when loaded into FCEUX or NEStopia?

~Ben
User avatar
TakuikaNinja
Posts: 449
Joined: Mon Jan 09, 2023 6:42 pm
Location: New Zealand

Re: Converting NES Tunes from NTSC to PAL?

Post by TakuikaNinja »

Are you referring to the region flag in the iNES header, or the process of detecting the video standard with code?
Bavi_H
Posts: 250
Joined: Sun Mar 03, 2013 1:52 am
Location: Texas, USA

Re: Converting NES Tunes from NTSC to PAL?

Post by Bavi_H »

I think SMB2J-2Q is asking how an emulator decides to automatically switch to PAL mode. Here are some ways emulators do that:
  • If the NES file name ends in "(E)" before the ".nes" extension, some emulators will switch to PAL mode automatically. This is based on the often-used filename tags (J) for Japan, (U) for USA, and (E) for Europe.

    Also, as TakuikaNinja mentioned, if the NES file's iNES header indicates the game is intended for PAL, some emulators will switch to PAL mode automatically. You can use the header editor in FCEUX or Mesen to change this header setting.

    Some emulators have a checksum-based database of common games and their correct header information. If the checksum of the game is found in the database and the database says the game is PAL, the emulator will automatically switch to PAL mode.

Just in case you're curious, TakuikaNinja is also talking about how some NES games can automatically choose appropriate timings:
  • Some NES games will detect if the NES is using NTSC or PAL and then choose appropriate music pitches, tempos, and other game timings. An example of this kind of detection is shown in the Nesdev Wiki page Detect TV system. Modern NES developers often add this kind of detection so that their game works well with either NTSC or PAL systems.
Guest34546

Re: Converting NES Tunes from NTSC to PAL?

Post by Guest34546 »

Their question was "how would I add a region auto-detect check", I think that's pretty clear cut.

SMB2J-2Q, see https://www.nesdev.org/wiki/Detect_TV_system
SMB2J-2Q
Posts: 271
Joined: Thu Jul 27, 2017 5:13 pm

Re: Converting NES Tunes from NTSC to PAL?

Post by SMB2J-2Q »

Individualised wrote: Tue Apr 11, 2023 5:46 am Their question was "how would I add a region auto-detect check", I think that's pretty clear cut.

SMB2J-2Q, see https://www.nesdev.org/wiki/Detect_TV_system
Thank you!

~Ben
SMB2J-2Q
Posts: 271
Joined: Thu Jul 27, 2017 5:13 pm

Re: Converting NES Tunes from NTSC to PAL?

Post by SMB2J-2Q »

In later NES games, the music speed was tracked independently of the video's frame rate, so for PAL the transition would be smoother. This is also true for many SNES games, including the PAL releases of Super Mario World and Super Mario All-Stars, which was able to properly transition its music from 60 to 50 Hz.

Hence, I ask, would it be possible for the NES SMB to separate music tracking from the video's frame rate and, if so, how?

Thank you,



Ben (SMB2J-2Q)
tepples
Posts: 23011
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)

Re: Converting NES Tunes from NTSC to PAL?

Post by tepples »

It's possible to separate the sound tick rate from the video refresh rate using a separate timer. The S-SMP has consistent tempo across regions because it has completely separate timers from the S-PPU. On NES, an MMC3 game could use the scanline timer, changing on which scanline to update sound from one frame to the next based on the desired tick rate. Or a game that doesn't use DMC could use DMC as a timer. PowerPak NSF player uses a timer in the NSF player's mapper.
SMB2J-2Q
Posts: 271
Joined: Thu Jul 27, 2017 5:13 pm

Re: Converting NES Tunes from NTSC to PAL?

Post by SMB2J-2Q »

tepples wrote: Fri Oct 20, 2023 11:40 pm It's possible to separate the sound tick rate from the video refresh rate using a separate timer. The S-SMP has consistent tempo across regions because it has completely separate timers from the S-PPU. On NES, an MMC3 game could use the scanline timer, changing on which scanline to update sound from one frame to the next based on the desired tick rate. Or a game that doesn't use DMC could use DMC as a timer. PowerPak NSF player uses a timer in the NSF player's mapper.
I wonder if converting SMB to using the MMC1 mapper might help, too? I do know the PAL release of The Legend of Zelda also has been properly optimized for 50 Hz, as shown in this gameplay video here:
https://archive.org/details/the-legend- ... +Game).mp4

~Ben