Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Yamaha DX7 chip reverse-engineering, part 6: the control registers (righto.com)
101 points by picture on Feb 7, 2022 | hide | past | favorite | 37 comments


Yes, another DX7 post. Author here if there are any questions :-)


I have a question (from part one); it's a clarification question.

> The digital implementation of frequency modulation starts with a lookup table that holds a digitized sine wave.

> The next step is to modulate the output by adding a modulation signal to the index.

In those paragraphs, you're saying that you start with a table of sine-function values.

This table has (for the sake of example) 4096 different values. I suppose in real life there may be many more.

then you read this table by incrementing an index between 1 and 4096. this happens many times per second and every time you increment the index by one unit. This will output a sine wave at a specific frequency determined by how quickly you increment this index (i.e. how often the table is read out).

So far alright, if you're adding 1 to the index 40960 times every second you'll a sine wave with a 10hz frequency (is this correct?)

but then, instead of adding 1 to the index 40960 times per second, you add 100 every single one of those 40.1k reads of the table? and this generates a sine with a frequency of 1000hz!?

this is quite frankly very surprising to me. The kind of thing I don't see myself coming up with easily; referring to the fact that it's possible to change the output frequency just by jumping around the table (instead of reading it all out one by one jump the index by 100 table entries) while keeping the number of times per second the table is read the same.

Finally, if the index increments themselves are read out from another sine wavetable, you get FM modulation... this is more reasonable but it depends on the previous very surprising (to me) way to change the frequency of a sine wave.

thanks for the great write-ups.


Yes, that's essentially how it works. You might think that jumping through the sine table in large steps would make your waveform too irregular. But that's what happens with any digital audio. E.g. a CD has music at 44kHz, so a 4400 Hz tone only gives you 10 points from a sine wave which would seem very irregular. But a low-pass filter smooths things out, so you end up with a nice smooth sine wave. (Look up Nyquist frequency if you want more details.)

One additional thing about the DX7 index is that you can think of the index as having 10 fractional bits, so you have much more accuracy in the increments. Otherwise, the frequency resolution is pretty bad because the frequency changes in big jumps when the index step changes by 1.


I would like to add the maybe counterintuitive fact (for people that never looked into that theory) that for "bandlimited signals", i.e. in your CD example a piece of music that does not have any content above 22.05kHz to begin with, that reproduction of audio will be perfect, i.e. look exactly the same as the input signal. (Well, assuming ideal filters and analog components, which isn't really possible, but you can basically get "arbitrarily close" to the representation of the original signal with your digital 44.1kHz signal assuming a bandlimited signal by choosing better and better analog components.)


Even if the wave isn't played with a wavelength of an integer number of samples, a good DAC will produce a pure sine wave as an output (as long as the sine is exact, and the wavelength of the wave is 2 or more output samples). If not you get aliasing (or the wave playing at the wrong frequency). This generalizes to non-sine waves, as long as you advance by the same number of waveform samples on each output sample, and the wavelength of the highest harmonic is 2 or more output samples.

In practice it's common to have non-exact sine/etc. waves, or not advance by an integer number of waveform samples on each output sample (generating output samples using various interpolation methods), both of which introduce high harmonics which get aliased to the wrong output frequency.

For more information on discrete-to-continuous frequencies and reconstruction, you can watch Xiph's "Digital Show & Tell" (https://xiph.org/video/vid2.shtml).


Thank you very much for linking this video. It's great viewing, and does much to dispel many commonly propagated myths.


> this is quite frankly very surprising to me.

If we let t be time in seconds, and f be frequency in Hz, the sine wave formula is y = sin(2pitf). The 2pi is the periodicity of the sine function. If f is 1, we sweep through 2pi once per second. If we let f be 2, then it sweeps through two times per second, and so on.

So, you can think of the lookup index as being the tf part, but with t counting in integer fractions of a second, with the caveat that you'll want to perform some interpolation between values.

If the waveform were more complex than a sine wave, then in the general case this "skipping agead" could cause distortion. A sine wave is one of a couple special cases (square wave being another, and arguably it's "cheating") where you're not skipping "too far" to cause distortion. (That relates to the Nyquist sampling theorem and low-pass filtering, as kens mentions)


A high-pitched square wave absolutely will have aliasing when played without interpolation. In Audacity, try creating a 30 second square chirp from 6000 to 16000 Hz, and listen to the weird and wacky frequencies far away from the intended frequency.


Because a square wave is actually infinitely many sine waves (at odd harmonic frequencies) added together. So, almost all of these will lie outside the Nyquist frequency, which is half the sampling rate for real sampling.

In practice, only the first few odd harmonics are strong enough to really matter, but with a high-pitched square wave you still need oversampling and lowpass filtering to get rid of those in the general case without aliasing[1].

However, if you choose the frequency of your square wave right (to make the sample rate an integer multiple), the aliasing products will just be reflected back to be exactly on top of the "actual" harmonics, neatly sounding like a perfect square wave again (in theory). Matching well with our intuition of what happens with the actual signal, if you do the "skipping" for such a square wave.

[1] Or maybe not if your goal is really only generating square waves: Just don’t generate these harmonics. Your 16kHz square wave without aliasing will just sound like a sine wave anyway, because your ear cannot hear its harmonics.


Are you by chance in touch with the gentlemen behind DexEd[1]? I've been using the Windows port of it and some instruments don't sound right, so I imagine there are some details DexEd doesn't quite have right yet.

--

[1] https://asb2m10.github.io/dexed/


I posted in the last DX7 chip thread about Dexed's interesting history. I know that at least one of the original developers frequents this forum. Dexed is a fantastic emulation. I remember Raph Levien mentioning that one of the most elusive details of the DX7's implementation that contributes to its signature sound is its quirky attack envelope stage. Also, one of the biggest remaining mysteries about the DX7 is the source of its trademark 'harsh' quality. It has a much harsher, warmer, and more distorted quality than any of Yamaha's other FM synths. Even decapsulating the OPS chip hasn't thus far definitively revealed the source.


No, I haven't been involved with DexEd. Hopefully, though, some of my analysis of the chip will improve the accuracy of emulators.


What's the expected clock rate for the logic? I think I missed that for context. The output is probably latched into the DAC at tens of khz, but there's so much bit serial stuff and time shared logic like the oscillators that it's much higher internally? Does it reach mhz?


3142144 Hz

4 times the DAC frequency.

Or, actually, 49096 * 16 * 4

http://yates.ca/dx7/Schematics%20&%20PCBs/DX7%20Schematic%20...

Top right of the diagram.


Almost π MHz!


Heh, I must have looked at that diagram a million times and never noticed that. Thank you!


Very good and deeply interesting work! As the owner of the later model, I have to ask: would you consider doing the same with a DX7II, if they are dissimilar enough at this level to warrant doing do?


My plan is to look at the DX7's other custom chip (the EPS), but I probably won't look at another synthesizer since I have too many other projects.


What's your favorite FM synth? :P


IMO FM8 is the best by a mile.

To me, you give up a little in basically sound quality(and that is probably debatable or depends on your taste) for a massively improved programming interface.

You can't go back to a hardware interface after that unless you just want to stick with presets.


Strangely enough, I'm not a synth guy, so I don't have favorites to recommend :-)


thats amazing


Not the author, but I'll answer as someone who has owned many of Yamaha's classic FM synths. Without a doubt I think that the original DX7 Mk1 is the most interesting. The latter 6-operator FM synths such as the DX7 Mk2, or the SY77/99 were definitely more advanced, and had a 'cleaner' sound, but they don't capture the same classic gritty quality of the original.


The Buchla 258 oscillator has amazing fm that sounds alive.


Are you working on an FPGA re-implementation? Basically everything with a DX7 chip in it is insanely priced (especially the PLG cards for the Yamaha MU-series, those are >$400), so this would be awesome to have.


I do wonder if it's feasible just to use some cheap off the shelf (COTS) general purpose ARM cpus like in Rasperry Pi computers and some code to perform the same calculations that Yamaha did in an ASIC in 1980's in real time. Even PIC microcontrollers today have a decent amount of computation for a couple cents.

Being latency sensitive here is definitely key.


Someone ported an emulator to the teensy: https://github.com/dcoredump/MicroDexed


It certainly is. The Korg Volca FM is implemented in this fashion, just to name one. From memory it uses an ARM Cortex-M chip for both the UI, and DSP. Many other modern synthesisers use COTS general purpose chips for DSP these days. At some point around the late 90s synths made the transition from being built around custom ASICs to using COTS DSP processor chips. It's hard to pin down exactly when this became standard. The Roland JP8000 (1996) used custom ASICs for signal processing, the Access Virus (1997) used a COTS DSP processor, from memory (Something from NXP?). The Korg MS2000 (2000) had a COTS DSP processor too. These days you can apparently achieve comparable performance with Cortex-M chips.


No question, just fascinating article, although I'm not an electrical engineer nor I'd be able to program these chips.


Is the idea this will soon yield a VST/emulator?


That has already been done (see: Dexed), think of this as the last steps in documenting what exactly it is that the DX7 actually does internally.

You can then use that to:

- verify that the emulators indeed get it all correct

- test your assumptions about how you thought it worked

- maybe program it to do things it wasn't strictly speaking meant to do


Keep them coming :)


This is a skill I wish I had because it just seems so interesting, but I'm badness enough at EE (quantitively bad: I failed out :D ) to not have any real hope :D


"The second way updates a single entry, allowing different notes to have different algorithms..."

So the chips allowed multitimbral operation, but the DX7 didn't support it?


Yes, that's how it looks, the chip supports multitimbral operation but the synthesizer doesn't. Disclaimer: I haven't tested this out, so I'm not 100% sure.


Seems like the sort of thing you'd use for a drum kit patch (each key is a different kind of drum), but I suppose that wasn't a standard thing when the DX7 came out and wouldn't be for awhile.

This demonstrates the factory patches; the train patch (#31) seems to have several different distinct timbres: https://www.youtube.com/watch?v=F3rrjQtQe5A


This is a theory that I would love to put to the test.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: