OPL3 C++ research implementation

An investigation into the behaviour of the Yamaha OPL3 chipset.
With a view to a more accurate emulator

Re: OPL3 C++ research implementation

Postby sto » Thu Mar 21, 2013 5:12 am

On a side-note, I finally added the LGPL 3.0 comments. I referred to you by:
Code: Select all
 * Some code based on forum posts in: http://forums.submarine.org.uk/phpBB/viewforum.php?f=9,
 * Copyright (C) 2010-2013 by carbon14 and opl3

Is that OK? On a side note, are you OK with the LGPL? I chose it to give more programs the opportunity to use the code, but I'm not sure if version 3 is OK or if I should revert to version 2.1.
sto
 
Posts: 60
Joined: Thu Nov 08, 2012 4:33 am

Re: OPL3 C++ research implementation

Postby opl3 » Thu Mar 21, 2013 8:15 am

Thanks for the credits, I appreciate that. I am ok with that as it is now.
But for the future, I have to think if I want to change that to something else than the generic "opl3", but I don't know if I want my real name there or just a better alias.

About the licence, I am not enlightened enough about the detailed differences to comment anything.
I know the main difference is that commercial software can link against a LGPL library without disclosing the commercial source code, but if the LGPL library is improved, they have to provide the changes to everyone. Well that how LIBSDL works as well. I think I have no problems with that. I still think you know better, and you wrote the implementation from the available documentation and pseudo-code.

The main thing to me is that the emulator is good enough, as I now understand it might be impossible to make it a 100% accurate clone of the original. We can still do more reverse-engineering, fill in the blanks in documentation, and base many different implementations on that documentation. You have your implementation, I have my own C code half-implemented, been thinking maybe this should be written in Matlab/Octave code as well, and maybe some day I might start an FPGA implementation (some year). I mainly got into this because I thought the previous implementations were inaccurate, wrong or had some philosophical architecture I thought was inferior compared to the real thing (like are the emulator samples skipped to match mixing rate or should it be resampled). But as things have shown, the differences and inaccuracies are pretty small, when used correctly there is hardly any audible difference in the generated tones under normal gaming conditions. I now understand that there are too many uncertainties when trying to compare actual sounds from emulator to real chip (for example the modulator and carrier could be one sample out of sync depending on at which phase of internal sample processing cycle the KON bit is turned on, and there is no way to know at which point a real PC writes and how a real chip can respond to that at arbitrary phase of execution). After good enough authenticity of the digital part, maybe some emulation of the analog parts would be nice, like the different models of OPL2/OPL3 DACs (16-bit range but only 10-bit resolution), half-sample phase difference between OPL3 channels (can anyone hear that anyway), and modeling of different analog filters (Adlib card had OPL2 with 4-pole Butterworth filter, later Soundblasters had OPL3 with no filters other than the mixer chip).

So that's my opinion, OK by me.

What do you think carbon14 ?
opl3
 
Posts: 55
Joined: Sun Sep 26, 2010 8:11 pm

Re: OPL3 C++ research implementation

Postby carbon14 » Thu Mar 21, 2013 12:33 pm

I'm more than happy with LGPL 3.0

carbon14 is the name I usually use for all my online presence so that's fine with me.

As for the rest of your comments, opl3, I agree that the real world behaviour of a chip is always going to be more subtle than the emulators. I don't believe that any of the current emulators will demonstrate the effect of the two oscillators being out by one sample, because they process each sample atomically (from the point of view of setting registers).

I believe that we can quantify that effect, and that's one of the reasons for my OPL2 project: by controlling the actual master clock and the data load, it should be possible to pin down the timings much more accurately, but this would probably only be of interest for something like an FPGA implementation. I can't see that you would ever build an emulator with these features in.

That said, one of the targets for my emulator is the Sega dreamcast. On this console, the audio is provided by a ARM co-processor with mapped memory. So theoretically I could run an emulator on the ARM sound processor, while the main console processor poked values into it's registers. This would potentially show the same kind of artifacts.
User avatar
carbon14
 
Posts: 124
Joined: Tue Aug 05, 2008 9:11 am
Location: York, England

Re: OPL3 C++ research implementation

Postby sto » Sat Aug 03, 2013 3:52 pm

It's been some time, but I have a few news:
  • The feedback uses only the 2nd-last sample value, not the average of the last two samples - see http://soundshock.se/phpBB2/viewtopic.p ... f2bec#1906.
  • I tried to implement the YAC512 processing and the two following op-amps, which work as a high-pass and a low-pass filter, trying to reproduce the SB sound.

Now, I have a question: The low-pass filter seems to be responsible for the centering of the audio wave around zero, though I cannot reliably calculate the filter coefficient, as I think that the output from the first op-amp (which is max. 25V) is damped through a resistor before it's fed into the second op-amp, which blocks me from calculating a factor using the slew rate. Can anybody enlighten me? The code in question is in Opl3::read() in the source repository, where you will also find some more detailed comments about my thoughts and the calculations I use.
sto
 
Posts: 60
Joined: Thu Nov 08, 2012 4:33 am

Re: OPL3 C++ research implementation

Postby opl3 » Sat Aug 03, 2013 9:49 pm

Hi Sto,

I am not 100% sure if the feedback is a sum of two previous samples, but at least the real chip and my emulation code matched this behaviour in my tests. It can be a coincidence or my test case was so limited that the real behaviour did not show. What I did was relatively simple, I just turned on a waveform at full volume and immediate attack, and the output happened to match. I have forgotten which waveform this was, but am sure I tried different feedback levels. I have to admit if the waveform was squarewave (and phase increment is zero), the real behaviour might not show. This needs re-testing with sinewave. Thanks for the link, I have to read it at some point.

Which op-amp filter you are referring to? Have you got any links, schematics or component values? Oh and a filter that removes DC offset is a high-pass filter, not low-pass filter. YAC512 datasheets don't have any filter, they only have the sample-and-hold buffers. And I have not seen any sound card with YMF262+YAC512 that would have a separate filter made with op-amps, they only have had simple inverting amplifier circuitry (with DC blocking capacitors) to mix YAC512 output with wavetable daughterboard output and then feed that into the mixer chip. The mixer chip might have some filtering and tone controls but that is another story.

Or are you referring to the anti-aliasing filter on a real Adlib card? That I have tried to model with two cascaded IIR biquad filters resembling the two second order low-pass filters, but I think the filter response is difficult to match with real analog filter when digital sampling frequency is only 49716 Hz while the filter cutoff frequency is about 15 kHz. But also other components affect the sound, not just filters. Good thinking about emulating the 10-bit DAC output resolution, I have thought about that too, but I thought the filter alters the sound more so I tried it first. I think for modeling the analog portions the sound should be oversampled, filtered and then resampled to 48 or 44.1 kHz for real-time output. But a sound editor like Audacity can be used to process the sampling rate conversion in non-real time if necessary when making compressed audio files or CD audio tracks.

So that's why the emulation of analog parts has not been the most important thing in my mind. Mainly my thoughts about enhancing the sound output would be to make the emulation core somehow configurable, for instance longer waveform tables with more resolution, so basically the full PCM output could be 24-bit instead of 16-bit. And maybe somehow generate 2x or 4x oversampled output directly, but so that all the timing and noise etc would still work at the native 1x rate, to avoid the possible problems the other emulators have when directly outputing at a resampled rate. Of course selectable emulation of DAC and different filters. The OPL4 and its YAC513 DAC have a third order filter suggestion in the datasheet. And selectable emulation of different OPL chip revisions that have different timing and output resampling, or even emulation of OPL clones that may sound wildly different in some cases.

Edit: After looking at your code comments, I think you have understood op-amps and their usage here wrong. They have open-loop gains (no feedback) in the order of 70-100 dB you mention, but in YAC512 datasheet circuitry, they are used as unity gain buffers, so that the sample-and-hold capacitor sees a very high impedance load (the op-amp input) so the voltage does not sag during hold stage and also in turn the op-amp output can drive a much larger load, such as on-board speaker amplifier chip, line level output or headphones directly. And on my Aztech sound card there is a different circuitry as I explained above, an inverting buffer powered by only +5V and -5V. Personally, I think there is no real need to model the sound of different op-amps. Really, the tolerance of the filter component values can be between 1% and 10% depending on manufacturer and price, which affects the sound more than just an op-amp. In addition, the Aztech had an error in the Ctb capacitor value, it was much too large (by a decade or so?) to keep stereo channels separated, so modeling this error would be way too complex.
opl3
 
Posts: 55
Joined: Sun Sep 26, 2010 8:11 pm

Re: OPL3 C++ research implementation

Postby sto » Sat Aug 03, 2013 11:21 pm

I have to admit that I only understood about 20% of the hardware stuff you wrote... one thing I want to change some day -- I have two books about electrical engineering here, but never managed to read them, and it looks that I don't get to read them within the next year, because my bachelor thesis needs to be written ;)

But I agree to make the code configurable so that it can create oversampled/more precise outputs. The problem that the signal from the OPL is filtered somehow still remains -- from subjective comparisons by ear I'd say there's at least a low-pass filter involved.

So: should I drop the filters again? Or do you have some easily implementable ideas about how to do it better?
sto
 
Posts: 60
Joined: Thu Nov 08, 2012 4:33 am

Re: OPL3 C++ research implementation

Postby sto » Sun Aug 04, 2013 6:47 pm

I played around with the one-pole filters in Audacity and found 50Hz and 18kHz to be good cut-off frequencies to let the emulator output match the youtube recording.
sto
 
Posts: 60
Joined: Thu Nov 08, 2012 4:33 am

Re: OPL3 C++ research implementation

Postby opl3 » Sun Aug 04, 2013 9:16 pm

Well, youtube recordings are done with lossy compression so the actual response could be at anyone's guess. It also depends on what is your current sound card, any processing by the sound drivers, in the DAC, components on DAC output analog path, load on the output (from the input of next device), and the recording/measuring equipment, etc.

The digital output to OPL DAC is known, and the DAC outputs what it is told as analog voltage, including any DC offset component. I have just thought that feeding the digital captures from real chip or emulator to sound card is enough, and then the analog parts after the sound card DAC (or in some cases in the DAC) do almost the same thing. They already remove the DC offset, may filter something, and drive the line output. Modern sigma-delta DACs may not even need a traditional anti-alias filter like a traditional DAC would need.

So I guess what I am saying is that back then with real OPL chips, different sound card models had a bit different analog output path response, just as current sound cards do. The best I can think of would be to optionally model the 10-bit resolution of the OPL DAC and the response of real Adlib card, or just some response if any filtering is wanted. Current emulators just skip the filtering and it does not sound so bad or different. Besides a lot of the difference (errors) in the sound could come from digital resampling done by software or sound card so that the output is something standard, many sound cards can only support few fixed sampling rates such as 44.1kHz, 48kHz and 96kHz, so everything else is resampled somewhere. I had an experiment to drop one sample per 29 samples to convert to 48kHz. I don't think I can hear a difference, but in real life there should be a digital anti-aliasing filter before lowering sampling rate, so that's why I was after modeling the analog 4th order low-pass filter with two cascaded biquad IIR filters. There was no high-pass system to remove DC offset, I didn't think it was necessary. Your single pole filters should be good enough.

Oh and the real master clock of OPL chip should be coming from a 14.31818 MHz oscillator, but 14.32 MHz is pretty close though. Original OPL2 compatibles used the motherboard's oscillator, divided this by 4 so their master clock was 3.579545 MHz. The timer chip frequency also relates to the same oscillator. I have not been able to verify whether the theoretical oscillator frequency is rounded to 14.318180 MHz, or is it the actual NTSC-based fractional value of 14.318181818181... MHz, but it does not really matter. Crystal oscillators are by default something like 10 ppm to 50 ppm accurate anyway, and approximating the sampling rate to 49716 Hz deviates less than 2 ppm. True, some sound cards have a bit different frequency for some reason, I think I have one with 14.32 MHz but I'd still say they are close enough.
opl3
 
Posts: 55
Joined: Sun Sep 26, 2010 8:11 pm

Re: OPL3 C++ research implementation

Postby sto » Fri Aug 09, 2013 6:15 pm

OK, I removed the filtering again, except for the YAC512. I wrote a small IMF player to get a broader base for comparison, and... well, listen for yourself:
https://www.youtube.com/watch?v=2OaI_GZZNyw; http://earvillage.square7.ch/downloads/opl3/dukina.ogg
sto
 
Posts: 60
Joined: Thu Nov 08, 2012 4:33 am

Re: OPL3 C++ research implementation

Postby sto » Wed Aug 14, 2013 7:36 pm

I've got two things that need to be verified on a real chip:

First: What envelope value is used? Does it first calculate the new value and then uses the new value (calc env; use env), or does it use the previously calculated envelope value and stores the calculated one for the next sample (old_env=env; calc env; use old_env)? For this to test, I think of an attack rate of 15 with square wave and a series of keyOn, hold, keyOff events to get a reference, and then a series of keyOns followed by setting the attack rate to 0 on the next sample. If the calculation is done the first way, there should be a high peak in the output, if it's done the second way, there should be a low peak.
I personally think the envelope is used delayed to reduce clicks in the output, but I need prove.

Second: The good old feedback... somebody in some other forum set two operators to feedback and used a square wave, then waited until self-resonance took effect, and checked the frequency to determine which samples are used for feedback (avg. last two, last one, second-last one). I don't know about the details, but it sounds reasonable to me.

Last (theory, no hardware): The KSL. In the well-known "OPL decapsulated" document, the author says that there were no other lookup tables than the sin/exp tables. So where does the KSL formula get its multiplication factors from? I tried to derive them from the sin/exp tables, but had no luck yet. Especially the somehow bitwise-shuffled attenuation per octave (6dB, 1.5dB, 3dB) bothers me, as I think they must have had very good reasons for providing such an odd interface for the KSL.
sto
 
Posts: 60
Joined: Thu Nov 08, 2012 4:33 am

PreviousNext

Return to Yamaha OPL-3 research

Who is online

Users browsing this forum: No registered users and 10 guests

cron