SNEcog for P2
Wuerfel_21
Posts: 5,006
Here is @Ahle2 's excellent SN76489 emulation object, ported to and optimized for P2. And I threw in some bug fixes, too.
- Has all features of P1 SNEcog
- Insane sample rates (configured for 1.4112 MHz (32x CD quality) by default)
- Fixed preset noise frequencies
- "Fixed" bug when noise frequency is zero/very low
This is really just a byproduct of my YM2612 emulation project that I've mentioned a few times. If you like chiptunes, I guess stay tuned for that. It kindof went through a few phases of "yeah, almost done" and "oh no this will never work out" already, so I guess we'll see when it is done.
EDIT: fixed version now attached...
zip
17K
Comments
Something's not right, and it sounds a bit messed up, particularly at the start of the tune in ExamplePlayRoutine. Pitch might be off too - but would need to compare against a P1 to know for sure.
Tested with audio pins on 6,7 with A/V board in P0-7 (3.5mm output) and FlexProp 5.3.1
Found the cause of the noise channel bug, this line needs to be fixed in ExamplePlayroutine.spin from this:
to this:
The pitch difference might be an artifact of PAL vs NTSC or the original being off (it used a strange 1.5 factor there, perhaps for rounding), or maybe me just imagining it. I think the new P2 code calculating the frequency looks right.
Good catch. Seems to not actually cause any issues on PropTool for either P1 or P2, huh.
Yeah that original frequency calculation was getting the right result with the wrong method. No, I think that example just uses a strange note table. The VGM dump player is spot-on, compared to the winamp VGM plugin on my PC at least. It also properly harmonizes with the YM2612 emulator (of which it is shoved into a corner off. The complexity gap between these two is astounding).
I did find a bug in the dump player though: the waitct and flipRegisters lines at the bottom should be swapped (flip first, then wait). Doesn't cause an issue for these simple SN76489-only dumps, but was causing missing notes and hickups with YM2612 dumps.
For a bit of fun I just added I2S output to this P2 SNECOG. It's still locked somewhat to the 250MHz due to the sample rate divisors and also constrains the pin order for now - this is what it uses:
DOUT - base
SCLK - base+1
LRCLK - base+2
MCLK - base+3
It only adds 6 instructions to the audio loop and still runs at 32x CD sample rate by the looks of it on the analog outputs.
For a 250MHz P2 it turns out the SNECog digital output samples at 44389 Hz (0.66% fast, so only ~11 cents high which is not especially noticeable). It's replicating the mono source on both L+R digital channels.
It worked with this PMOD-I2S board I have:
https://reference.digilentinc.com/reference/pmod/pmodi2s/reference-manual
I'm hoping it would also work with one of these too (no MCLK needed for this board, which reduces the constraint on the divisors and would allow other P2 clock rates):
https://www.adafruit.com/product/3006
Neato!
And yeah, I've suspected it to go slightly off-pitch at high rates due to rounding error. Would be neat to move all the constant calculations to runtime and run at a fixed clkfreq/N rate.
Anyways, the YM2612 is probably gonna drop either today or tomorrow, so you can have more bits of fun with that, I guess. Code itself is as good as I think I can get it, just needs to be cleaned up a bit and have some nice example programs made.
It would be good to have some type of mixing COG that could take input from these different chiptune emulators and combine them so that the final output was some mix of these various sources and samples, and could all be output over analog pins and/or I2S (maybe SPDIF). A while back I'd guessed that was what @Ahle2 had in mind with the work he did earlier on his reSound project.
Yeah, he said he wanted to do smth like that. My YM2612 emu already has SNEcog built-in, but running at a fairly low rate (~53 KHz, same as the FM). Okay enough for most Mega Drive tunes, but ones that make heavy use of the PSG tone channels sound kinda aliased. I've attached a recording of the Streets of Rage intro tune...
I found an issue with the I2S clock output phase not being 100% right. It needs a slightly different init sequence to cleanly start up with the data in sync and phase....still figuring it out. I need the rising edge of MCLK to be in phase with LRCLK transitions and with SCLK falling edges (and align these to data transitions, with the first MSB one SCLK into the LRCLK period). The code above is not doing this yet.
UPDATE: I patched the code above to the new version which seems to align the clocks the way I want. Still not sure why I need to invert the MCLK output to make it do what I want. The clock init sequence timing is still a bit fragile I expect.
Great work Wuerfel,
Yeah the SN76489 is the most simple PSG I have come cross so far; It even makes the AY-3-8910 seem like something really advanced. If I remember correctly, it took me just a (fraction of) day to implement including the .vgm player and all. I'm amazed there even was bugs in it?! It "shouldn't" be possible considered the simplicity of the PSG. But I remember that the vgm music I ran through it sounded fine?!
So now we just need a MC68000 emulator, maccas TMS9918A emulator on steriods and a little other stuff to have a Sega Genesis emulator!
rogloh,
Actually you could already mix different non buffered "realtime" audio sources using reSound, as long as the sample format is one of the supported (very likely). Just point one of reSounds input channels to a memory address where the sample is updated and set sample length to 1 and loop size to 1, to effectively just read the same sample address each mixing period. You can set the pan and volume for that channel just as usual. The I2S output is on my ToDo list, but it turned out that the P2 had got some amazing quality DACs built right in (that was a big surpise to me considered the P1 equivalent... ooooh my). So that is WAY down the list of things to implement.
Yeah I2S is pretty easy to achieve with the synchronous serial mode, so hopefully you get to add it at some point. The main issue might be generating the clocks. I just did it synchronously with the P2 clock but for more flexibility perhaps NCO mode is required if whatever jitter it introduces is acceptable. If you don't need an MCLK, and just the SCLK+LRCLK it probably makes things somewhat easier.
Having reSound do the mixing is nice. I like the idea it can mix in several PCM sources with the PSG ones and also could do MOD playback etc. Very flexible.
Yeah, reSound should be able to mix most types of digital audio sources/signals using different sample rates, bit depths and (raw) audio formats without problems.
Thread split to Console Emulation thread here : https://forums.parallax.com/discussion/173381/console-emulation
Good job!
Was looking this over while trying to get AYCog to work. Found a minor bug in the init code. Shouldn't have mattered, anyways, but something something perfectionism