AY-3-8910 sound chip
pullmoll
Posts: 817
I thought I had read somewhere that one of the forum members was going to try to create an object that emulates this chip? I can't find that post (or did I dream it)...
Anyway, I have been trying to convert attached C source into PASM, but I'm yet unsure if it will be feasible to emulate the AY this way. The attached code generates chunks of audio data and needs a streaming device (cog) to output the data at a constant (sample) rate. This would mean 2 cogs, one to generate the data and one to actually play it. I would rather have one cog doing all the work, if that is possible. I think it depends on how fast the 3 sound channels and the noise can be calculated in PASM. If the calculation is faster than the sample rate, the samples could be output immediately after calculation and the sample rate could be locked by using a waitcnt.
Perhaps those who know a bit more than I do about sound on the Propeller can elaborate on this issue?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Anyway, I have been trying to convert attached C source into PASM, but I'm yet unsure if it will be feasible to emulate the AY this way. The attached code generates chunks of audio data and needs a streaming device (cog) to output the data at a constant (sample) rate. This would mean 2 cogs, one to generate the data and one to actually play it. I would rather have one cog doing all the work, if that is possible. I think it depends on how fast the 3 sound channels and the noise can be calculated in PASM. If the calculation is faster than the sample rate, the samples could be output immediately after calculation and the sample rate could be locked by using a waitcnt.
Perhaps those who know a bit more than I do about sound on the Propeller can elaborate on this issue?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
txt
24K
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Leon Heller
Amateur radio callsign: G1HSM
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
http://forums.parallax.com/showthread.php?p=863861
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
The SID chip is many times more complex compared to the ay8910, and still it was possible to do a quite good emulation of it in just one cog.
I even managed to fit the "analog" multimode resonance filter running in just one cog at a sample rate of near CD quality.
The AY8910 lacks almost everything that made the SID chip so complex for it's time.
If we take out Multimode filtering, Oscillator synchronization, Ring modulation, Variable pulse width, Saw waves, Triangle waves and combined waveforms from SIDcog we pretty much end up with an ay8910.
Then of course we have to alter the registers and severely cripple the envelope part.
We would probable end up with an emulation with a sample rate of almost twice that of a CD thanks to the simplicity of the chip.
gadgetgangster.com/scripts/displayasset.php?id=344
Everything you hear is generated by one cog at 31Khz and output with PWM trough a RC filter.
Ok, then I may try to continue with what I began. The AY is really simple, that's true. And still it was widely used on computers and in arcade games, up to 5 chips per game it seems. The comments in the C source pretty much describe every important aspect of the chip and I think I can finish it. I just have to rethink the core update function to do everything for one sample only.
Thanks,
Juergen
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Post Edited (pullmoll) : 5/15/2010 4:51:18 PM GMT
AYcog features:
- 60 kHz sample rate
- YM2149 or AY-3-8910 register structure
- Supports all waveforms ( Noise wave and 50:50 square wave )
- Can use advanced envelope tricks to produce other waveforms than square or noice (like the real thing)
Usage:
- Start AYcog with the public function "start(right,left)"
This function starts AYcog with audio out on the pins specified and returns a pointer to the first register of the the AY-3-891X.
- Put values in the 16 AY-3-891X registers and it should start making sound.
- One small difference from the real deal.
It's important that you set the 4th bit of the envelope shape register high everytime you change the register.
This is because there is no other way for the emulation to know if you have retriggered the register.
As soon as the emulator has read this bit it automatically sets it low again and it is ready for a new retrigger.
Example. If you want to put the value 9 (Decay) in the envelope shape register, you should set bit 4 high as well, resulting in value 9 + 16 = 25.
If you don't set this bit the envelope will not work.
/Ahle2
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
http://www.propgfx.co.uk/forum/·home of the PropGFX Lite
·
Try this code for a complete runthrough of all possible AY sounds.
LOL
·
I will correct that.
next the hammond C3?
·
Every PSG emulator I do tend to be simpler than the one before.
The only PSG I can think of that is more simple than the AY-3-891X is the two channel TIA chip used in Atari 2600.
The SID chip is A LOT more advanced compared to the AY-3-891X.
I think 31kHz samplerate for SIDcog and 60kHz samplerate for AYcog speaks for itself.
Post Edited (Ahle2) : 5/18/2010 10:48:54 PM GMT
Thank you much! That was really quick!
Is there probably a way to have it output on a single pin? I tried to detect if left == right and set a flag in that case, so that ctrb and frqb wouldn't be used. Unfortunately I don't hear anything at all yet. I have to fix my sound circuitry first (I use 1 pin #24 on the DracBlade). Edit: That output is still working with TRS80 and the single duty mode, so it has to be my modification that's wrong... I just hear a click when the cog is started and that's it.
Later you said you're going to fix this, so I should probably just map the first 8 registers 1:1 from the cgenie io.spin?
Edit: I think this is easy to fix. Just test EnvelopeShape, #16 and do the following things if_z only. Then or EnvelopeShape, #16 and write it back to hub RAM!?
Right now, after adding the AYcog to the list of objects, some games don't want to run anymore. This has to be a bug to do with memory somewhere, because also BASIC is behaving strange and giving me ?OM errors (out of memory). Anyway, that's my problem.
Thanks again,
Juergen
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Post Edited (pullmoll) : 5/19/2010 2:06:09 PM GMT
When you get your circuit right, please let me know what it is (even if it is just a resistor and capacitor) and I'll add that to the next board.
Sound is going to be a fantastic addition. Hmm - is there a cog free on the MP/M emulation?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
Assuming a 500Ohm aux input on the amplifier and max. wanted 1Vss level, you should probably go with a 1k1 resistor and perhaps a 1µF electrolytic capacitor in series with the output!? Perhaps like this:
VT100 initialized, 0 cogs free.
Nope. We're out of cogs.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Post Edited (pullmoll) : 5/19/2010 2:04:07 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Visit some of my articles at Propeller Wiki:
MATH on the propeller propeller.wikispaces.com/MATH
pPropQL: propeller.wikispaces.com/pPropQL
pPropQL020: propeller.wikispaces.com/pPropQL020
OMU for the pPropQL/020 propeller.wikispaces.com/OMU
pPropellerSim - A propeller simulator for ASM development sourceforge.net/projects/ppropellersim
I do an or with #16 for writes to register #13.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
It was on my ToDo list anyway. You just gave me a reason to do it before year 2020. [noparse];)[/noparse]
start(0,24) will do the trick.
The start function takes care of everything including disablling of ctrb or ctra if either left or right is set to 0.
I know, I was just stupid for not doing exactly that from the beginning... (dooh)
Okey, keep on debugging. [noparse]:)[/noparse]
BTW, I will upload a new version with some changes shorthly.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon McPhalen
Hollywood, CA
Otherwise you might want to test to change
to
(Remember, that's 3 changes, one for every channel)
WARNING
One thing to remember for emulator coders.
When writing to register 15 you have to "and" the byte with 15 / $F to not alter the "reset envelope flag".
Else the sound may be wrong if the emulated piece of code tries to (incorrectly) set bits 4-7 of the register.
Edit....
pullmoll,
I just saw that you ACTUALLY was talking about register 13. That's the low byte of the 16bit envelope period register.
What are you talking about?
Post Edited (Ahle2) : 5/19/2010 7:53:59 PM GMT
That gives a slightly better set of sound effects, but there is still something seriously wrong.
Unfortunately I have not yet found the bug that causes PAINT.CMD to not work anymore. I guess you could judge by common sense that an accord of 3 tones, right after the startup of a game, that stays until something happens can't be quite right. I can describe the simple game FUSS.CMD sounds. When you move normally, it plays a little tune of 3 or 4 notes. When a rotating cross appears, there is a sweep from low to high frequencies which dies after abt. a second. Finally, when you eat one of the crosses that makes you immune to the poisoned red dots, there is the sound that you now hear right from the start.
All in all it looks like some or even most effects are done, but at the wrong times. It's hard to describe that. I could try to get my C version Colour Genie emulator up and running, because it has perfect sound.
I did that and it makes no change.
According to my specs, register #13 (zero based) is the envelope shape register. The enumeration is in the text file I attached to the first post, the C source of the AY-3-8910 emulation. REG_EFINE (the low byte of the envelope period) is register #11.
For the records, here's the enum:
I posted an updated version cgenie-0.1.5 in this thread.
Edit: Updated again, because I found the reason for the strange sounds: the value REGISTER_OFFSET has to be 1, just like for the YM chip. Where did you get your port numbers from? They're wrong for the amplitudes and everything else following.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Post Edited (pullmoll) : 5/20/2010 6:11:59 AM GMT
According to the official specs the AY has a 2 byte gap between the "enable register" and "channel A amplitude register".
http://map.grauw.nl/resources/sound/generalinstrument_ay-3-8910.pdf
The YM-2149F on the other hand has the specs you are talking about.
http://www.ym2149.com/ym2149.pdf
Take an unaltered version of AYcog_V0-16.spin·and just enable the YM instead and see if that's works.
If so, it seems like the Color Genie actually has an YM chip and not an AY.
/Ahle2
by looking at the AY-3-8910 datasheet I got the feeling that R0..R7 and R10..R17 in register name notation is OCTAL and not decimal.
So registers are really still R0..R15. The width of register select pins (page 5-19) is 4 bits, so it make sense.
In the end the register map should be identical for both chips.
I also tried to match this hypotesis with some other source (http://www.atarimagazines.com/v4n7/stsound.html), and that seems to confirm it.
But consider I never programmed such a chip so I could be wrong.
Regards
Alessandro
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
I did all of my coding based on the official AY-3-8910 documentation and I didn't realize they used octal numbers for registers in the AY-3-8910 doc but decimal numbers in the YM-2149F doc.
pullmoll, it's STILL important that you set all constants to the YM setup and not just "REGISTER_OFFSET=1" like you did
It should look like
Otherwise envelopePeriod register will be faulty.
What about attached version 0-17? I removed the constants altogether and made the AYregisters a parameter, so that the calling object defines the register set. That way it is easy for a caller to give useful names to the registers and/or to deal on its own with the digital port A and B.
Also note that an envelope period of 0 is actually half the length of a period of 1, i.e. it is not zero! This info is from the MAME project's AY/YM emulation.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Post Edited (pullmoll) : 5/20/2010 6:51:40 PM GMT
Here is an example of playback of AY register dumps from various AY tunes.
Unpack the ym files to a freshly formated SD card and run "AYDumpPlayExample.spin" and enjoy.
Cool! Not as nice as SID songs, of course, but still nice.
Here's a suggestion for an openNextFile that selects just *.ym files - the others sound a bit strange
The player works with my modified -0-17 as well. It seems the Microtan could have an add-on with 2 AYs, so I'm going to add your code there too. With the caller defining the AYregisters that's no problem.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Post Edited (pullmoll) : 5/21/2010 12:25:19 AM GMT
AYcog v0.20 improvements:
- 13% smaller
- 2.08 times higher sample rate. (125kHz)
- Fixed some small timing errors
- Logarithmic volume for "fixed" amplitude values as well.
(v0.16 had logarithmic volume when using envelopes only)
FAQ
Q. Why would it matter to have a better sample rate than twice (according to nyquists theorem) the human range when people can't hear those high frequencies anyway ?
A. To minimize audiable aliasing distortion when playing high notes.
Q. How come AYcog has a sample rate 4 times that of SIDcog when both PSGs has got 3 audio channels ?
A. The SID chip is many times more advanced compared to the AY-3-8910, plus it has got a multimode analog filter.
@pullmoll
It's very important that the AY registers are aligned to long address plus a two byte offset otherwise the getRegister subroutine will fail to get the correct values.
Valid addresses are:
0 + 2 = 2
4 + 2 = 6
8 + 2 = 10
12 + 2 = 14
16 + 2 = 18
etc
etc
That's the reason why I don't think it's a good idea to to let the user choose the address.
Btw, I've added your modified version of openNextFile to the new dump player example.
I will look at the division by zero problem you were talking about when I find the time.
/Ahle2