Showing posts with label JX-3P. Show all posts
Showing posts with label JX-3P. Show all posts

Monday, March 23, 2020

Cross modulation on JP8, JP6 and JX-8P

I was trying to find info about how the JP8 crossmod works last night, but ended up answering a post about it instead. Here is what I wrote:

TL;DR:
JP8 and JP6 crossmod is exponential FM of DCO 1 by DCO 2, JX-8P is amplitude modulation (ring modulation) of DCO 2 by DCO 1 (plus sync if wanted).
Details:
All of this should be fairly easy to figure out from the service manuals for the various synths.
Right now I'm looking at the JP8 service manual. Here, the output from VCO 2 - tapped after the waveform selector - is fed back to the exponential (v/oct) input of VCO 1. There is nothing going into the reference current input of VCO 1 (the circuit around op amp 1A on page 12 of the service manual), so the JP 8 has no linear FM.
The signal from VCO 2 goes through IC18A, which is a BA662 OTA, this acts as a voltage controlled amplifier/attenuator, and this is what is controlled by the panel potentiometer.
The same is the case for the JP-6, although here the signal is fed through a CEM3360 VCA. It is still sent back to the exponential input of VCO 2. Nothing is fed into pin 13 of the CEM3340 VCO so the JP-6 has no linear FM either.
The JX-8P is completely different. It doesn't have VCOs, it has DCOs, meaning the frequency is digitally controlled. It does NOT let the output of DCO 2 control the frequency of DCO 1, neither exponentially nor linearly. Instead, when crossmod is enabled (pos 1 or 2 on the PG-800 switch), the output of DCO 1 controls the amplitude (volume) of DCO 2, which I guess means that the output of DCO 2 is now DCO 1 times DCO 2, or exactly what is described as ring modulation in figure 2 here (given that it follows the gain requirements stated): https://www.keyboardmag.com/gear/on-synthesizers-amplitude-and-ring-modulation
PS: This means that, unlike what OP says about crossmod on the JX-8P, DCO 1 does NOT modulate the FREQUENCY of DCO 2, it modulates the AMPLITUDE.
In the circuit diagram the control for this part of the X-mod is labeled 'Metal', so it is very possible that this has the same effect as 'Metal' on the JX-3p, which is also described as a ring modulator type of sound. Interestingly enough, I cannot find any similar circuit on the JX-3p.
The JX-8P (and JX-3P) does also have a sync input on DCO 1 going to Q18, which is the transistor that resets the sawtooth of DCO 1 (i.e. sets the frequency). Sync comes from the same input that resets DCO 2, so whenever DCO 2 resets, so does DCO 1 (which means this is just normal hard sync I guess).

Sunday, November 18, 2018

PG-200 busy line

When building the MPG-200 for the JX-3P, I discovered that the busy line is hardwired via a pullup resistor to +5V, in effect tying it to logic high.

Because of this, I decided to ignore it altogether. But when trying to get the MPG-200 to work with the MKS-30, I discovered that this synth actually DO control the line.

So what actually happens when the busy line is pulled low?

As expected, the PG-200 does not transmit anything while the line is low. Still, I was curious what happened afterwards, when the line was released again - did the PG-200 just ignore whatever had happened during busy, did it queue up events or did it send the new stable status?

Well, a bit of both really. It keeps the last state from before it was blocked. Then, once busy is cleared, it sends first the state it had before blocking, and then the state after blocking. This happens for both switches and potentiometers.

Friday, July 21, 2017

XM8 filters

I want the XM8 filters to be as flexible as possible. I've studied the various IR3109 based roland filter implementations and the CEM3320 ones found at Electric Druid, and found designs for state variable filters based on both.

I am thinking about having exchangable filter cassettes, possibly with two identical filters per cassette. I tried to find a common control scheme, but right now I think that just using a shift register to serially control the filters will be the most flexible - that way variations can be software controlled instead of implemented in hardware.

I also want to have two filters per voice, configured in either series or parallel - one state variable and one permanent LP.

IR3109
I've found six different implementations using the IR3109 chip or similar. The JP4/6/8, the Juno 6/60, the JX-3P and the MKS-80 all use the IR3209. The MKS-7, MKS-30 and Juno 106 use the 80017a filter chip which is basically a combination of an IR3109, two BA662 and some additional components. I have not studied the use of these in detail, just compared the resonance and control circuitry.

SH101 and MC202 also use the IR3109, I have yet to look at those.

There seems to be a progression in the circuit through the years. Exact component values varies but all except two of the implementations use the same circuit for the filter part. The resonance feedback control and the cutoff frequency control circuits are quite different between the synths.

The JP-6 and the MKS-80 stand out however. The JP-6 has a state variable filter that allows both HP, LP and BP filters - the two first 24dB and the last 12dB. It would be easy to add 12dB HP and LP too, but this has not been done. The MKS-80, weirdly enough, has the same configuration as the JP-6, but hardwired to a LP.

The JP8 and the Juno 6/60 uses the exact same filters/component values, except for a few minor differences in the resonance feedback and cutoff frequency control. The JP8 can be tapped at 12dB or 24dB whereas the Juno is 24dB only. An interesting thing to note is that the Juno 6 datasheet indicates the CV for cutoff: 0.48V/oct.

All implementations have a posistor in the control circuit to compensate for temperature variations. The JP6 and MKS-80 have a posistor in the resonance circuit too.

State variable filter
I currently consider these implementations:
- The JP-6, with the added option of 12dB HP/LP
- The Elka Synthex CEM3320 based filter
- The CEM3320 multiple identity filter
- The Wasp filter.

Permanent LP filter
- The moog ladder filter
- possibly the Juno filter, if it actually sounds different than the JP-6 filter
- Possibly a SSM2044 (SSI2144) based filter - Korg PolySix or MonoPoly
- Korg MS20
- ARP4270 (ARP 2600)
- EMS Diode ladder filter

I will start out with the JP-6 and moog ladder filter and go from there.

Interface
SVF
digital: serial input, clock, load
analog: resonance CV, cutoff CV

LP
digital, 12dB/24dB switching
analog: resonance CV, cutoff CV

Sunday, January 29, 2017

DCO

I've started working on a DCO circuit, as this will probably require fewer (but perhaps more expensive) parts and be easier to tune.

I want the DCO to work for all midi notes (C0-B8) and be within 1 to 3 cents of the correct frequency for all notes.

Looking at the Juno 6/60/106 and JX-3P DCOs I've so far set up a google docs spreadsheet, calculating all periods to get correct frequencies and the necessary voltages (currents) to get a constant amplitude.

A short intro to DCO theory

DCOs are (often) based around a relaxation oscillator, exactly like a saw core VCO (http://xonik.no/theory/vco/reference_current.html - this also explains how the capacitor is charged). A current charges a capacitor and a transistor short circuits and discharges it to restart the period.

DCOs are stable because they use a digital timer to control the discharging of a capacitor instead of relying on an accurate charging current - the period and thus frequency is computer controlled and highly accurate. For the saw ramp to reach the same amplitude as the charging period (time available to charge the capacitor during a cycle) changes, the DCO instead changes the charging current. As the frequency changes exponentially with rising notes, so must the charging current.

In my spreadsheet I have calculated two important aspects for a physical circuit - the accuracy of the timer generating the period/frequency and the accuracy of the charging current generation.

Frequency

A microcontroller timer has two properties - the minimum period and the maximum count. These limits the length of an output period and the accuracy of its length. A 16bit timer can at most count to 65535 and has a maximum accuracy of +/- 0.5 times its minimum period. For example, if the timer frequency is 8MHz, each tick of the timer is 0.125uS and the accuracy is thus +/-0.0625uS. Its maximum output period length is 65536 * 0.125uS = 8192uS or 8.19mS. The consequency is that a 16 bit timer running at 8MHz has a minimum output frequency of 1/8192uS = 122Hz. (Here we assume that the timer restarts the period whenever it has counted to its maximum).

The accuracy limitation is most important to the upper end of the frequency range. The maximum needed frequency (B8 = 7902,13282Hz) has a period of 126,55uS. An inaccuracy of 0.0625 equals an error of about 0.05%. The human ear is able to hear a difference between two notes played after eachother of about 10 cents/0.6% if the notes are sine waves, less if they are complex tones. Thus, this inaccuracy is well within what is acceptable.

But what can we do to make the timer count long enough for deeper notes? We can either use a bigger timer (32bit) or more often, use a prescaler that divides the clock running the timer. If we use a prescaler of 2, the timer frequency changes from 8MHz to 4MHz, the minimum period changes from 0.125uS to 0.25uS and the maximum time from 8.19mS to 16.38mS. This makes the lowest possible frequency 61Hz. Changing the prescaler to 8 gives a minimum frequency of 15.25Hz, which is low enough for C0.

Unfortunately, increasing the prescaler also decreases the accuracy as the minimum period gets longer. I have set 3 cents as the maximum error acceptable at the highest frequency. Using a prescaler of 8 makes some of the notes at the top of the frequency range fall outside the target accuracy.

In short - using a 16bit timer, we cannot use a single prescaler value and achieve both the frequency range and the accuracy needed. To solve this, we need to change the prescaler somewhere towards the lower end of the frequency scale. To get a constant time used setting up the timer, i propose always setting the prescaler when reloading the timer.

Amplitude

DCOs use different ways of creating a control current. As mentioned previously, the necessary charging current changes exponentially as the notes change. The Juno 6/60 seems to use an exponential converter (I may be wrong about this though, I haven't studied it closely) to achieve this, but such a converter has the same temperature dependency problems as the one controlling the pitch in a VCO (but the effect in the DCO is on the amplitude, not the pitch, and will thus not be as noticeable).

The Juno 106 and JX-3P however just feed the output of a DAC through a resistor and into the integrator (saw ramp generator). This means that the DAC must generate a voltage that accurately approximates the exponential curve needed throughout the note range (the voltage is converted to a current through a resistor). This may be problematic as the rate of change is very small at one end then suddely very large at the other.

I've once again used the spreadsheet to calculate first the real the charging voltage needed, then the current created using a DAC of arbitrary resolution. By rounding off the needed current to the nearest value achievable with the DAC, then multiplying with the per-step voltage, then using the capacitor charging formula with the known period as t, we will find the real amplitude of the wave and thus the maximum error per note.

Using a 16bit DAC and charging a 1nF capacitor through a 100k resistor, we are able to charge the capacitor to within 0.02V (of a maximum of 5V), or 0.4% of the wanted amplitude for all notes.

When calculating the capacitor charging, I've assumed that we can follow the same formula as in my older VCO research, where I found that the voltage across the capacitor at a time t after the charging starts, V(t) = t * I/C. I is found by dividing the DAC voltage Vdac with the input resistor R. Rearranging for Vdac gives us Vdac = V(t) * C * R / t, and to calculate the resulting max charging voltage, V(t_max) = Vdac * t_max / C * R.

My calculations can be found here: https://docs.google.com/spreadsheets/d/1ROhU0L4UZ2CWLu3h5LHopaB0Jv7ewNRziecj5I6D27M/pub?gid=0&single=true&output=pdf

Further work:
- Figure out how to calculate timer values and dac settings (lookup tables?)
- How to interpolate efficiently between values in the lookup table to reduce its size while still allowing input pitch to be a 16 bit value
- How to do DCO sync
- Possibly: Changing timer/charge voltage in the middle of a cycle in order for the DCO to respond instantly (the Juno DCOs apparently only change pitch at the start of a cycle.

Wednesday, March 13, 2013

Stand alone prototype finished

The first fully functional MPG-200 prototype was finished and shipped yesterday. It features automatic switching between midi and pg-200 mode (with a small modification to the JX-3P), and tries to minimise the fact that switching cannot be done very quickly. In particular, it stores any note off messages received while in pg-200 mode and sends them as soon as it reverts back to midi mode.

The following features have been implemented:
  • all switches and pots from the PG-200 except for write and manual
  • midi passthrough - lets all midi messages not destined for the mpg-200 through
  • note off protection to prevent hanging notes
  • automatic switching between midi and pg-200 mode to allow full control of the JX-3p from a DAW or similar
  • three modes - pg-200 only (blocks midi but keeps delay to a minimum), safe mix (mixes midi and pg-200, but ensures that no message is interpreted as the wrong type by the jx-3p by introducing a "safe time" between modes), mix (switches instantly).
  • queueing of messages in case they arrive faster than the mpg200 can handle them.
  • default CC-to-pg200 mapping

Still to be implemented are
  • Config of CC-mapping and other parameters via sysex, stored to flash memory
  • Configurable midi channel
  • Autosensing of when the jx-3p has noticed a mode change
  • Configurable ranges for the potmeters
The mpg-400 prototype. The "production model" will be using an 8 leg microcontroller with a built in crystal, and will be using at least 7 parts fewer than the prototype.

Tuesday, January 1, 2013

Oh the horror!

I have incredibly bad news to bring to the world at the start of the year. To my horror, I've discovered that the switch between midi and PG-200 modes on the JX-3p is scanned like any other key on the front panel of the JX-3P. Using my logic probe on the scan line while turning both a dial and playing notes at the same time, I have observed the following:


  • The scan frequency varies widely depending on how much work the JX-3P has to do (as is to be expected I guess)
  • The minimum period between two scan cycles is 11.7ms (!) while delays of up to .23 seconds (!!) also occured. This means that the absolute fastest switch between midi and PG-200 data is about 12ms and that I have to use a much higher period to be reasonably sure of not dropping any bytes.



In this screenshot, the first waveform is the serial data (midi/pg-200), the second is the mode-select signal (switches between midi and pg-200), the third is the scanning - notice the big period of blackness in the middle of the screen, here the JX-3P has been working hard and not had the time to scan for changes, resulting in a dropped midi or pg-200 byte. The fourth is the result of the scanning, whenever a scan occurs and the mode select signal is 0, a 1 is returned to the microcontroller - this is seen as long stretches of 1 on the fourth line, in the parts where the scanline still changes rapidly.

This is by far the biggest problem I have faced while working on the mpg-200, and I am afraid this one cannot be solved easily as it is directly related to the way both the hardware and firmware of the JX-3P is built.

I have tried using a "settle time" after changing the mode of about 100ms, that seems to work fine for most hand turned potmeters etc, as long as one does not play fast and turn rapidly at the same time. However, even this means that one has to wait at least 100ms after changing a controller before a new note is pressed (or released). If not, the note will be delayed or not played at all.

So - one can do filter sweeps as long as you hold down the same note, but rapidly changing parameters while playing will probably not work very well :-/


This seems to me like a show stopper for much of what I wanted the mpg-200 to be. It can still be used for tweaking the JX-3P from a daw, but prevents much of the automation that would be cool.

What a bad way to start 2013...

Sunday, December 2, 2012

Ping without Pong!

Eureka! The final major mystery is solved!

Last night I got the MPG-200 working, but when I powered it up again this morning, nothing happened. It was completely dead again and the JX-3P didn't react to any of the input - just the way it has been for the last few weeks.

I opened the JX-3P again and measured the logic signals going to its microcontroller, and sure thing, they were coming through just as they did last night. Still, no reaction.

It then occured to me - what if the PG-200 sends a special message when booting up? To 'ping' the JX-3P, telling it that it's present?

I reconnected the PG-200 and this time I started the recording before turning on the power on the JX-3P. And what do you know - there, just before the first output from the PG-200 controllers, it sent two bytes: An address with the value 128 and an empty (0) data byte.

It actually doesn't send the Ping on startup, it seems it waits untill the first time a controller is changed. I have to look into it to see if this is significant. Anyway, after implementing the same scheme on the MPG-200 (or rather, just sending the Ping 1 second after startup), it works like a charm! Now the MPG-200 works every time :-D

I have however managed to consistently overloading the JX-3P by sending to many bytes. I assume that this is because I ignore the busy-line. When this happens, the JX-3P shuts down (the microcontroller at least) and it stops producing sound. It is quickly fixed by turning power off/on, but this has to be fixed.


Saturday, December 1, 2012

Finally - the MPG-200 is alive!

Success at last! Tonight the MPG-200 successfully controlled the JX-3P for the first time! The current circuit uses the same japanese transistors as the PG-200, but I am still not sure that is necessary. I have tweaked the delays between the address and data bytes (the timing in the PG-200 is about 70uS between the last low of the address byte and the first low of the data byte) and between two blocks of data (PG-200: at least 17.5mS). The current delays for the MPG-200 are 91uS and 20.4mS respectively.

Now I have to get this to work with a more custom delay (or at least drop bytes instead of queueing them up, currently I get a 'delay'-effect of sorts instead of stepping. I also need to figure out how to generate bit masks for the switches. 

Sunday, November 11, 2012

Almost there - MPG200

Well, I thought that tonight would be the night when I got the MPG-200 up and running with the JX-3P for the first time. Alas, I failed miserably ;-)

I've checked the output from both the MPG-200 and the PG-200, and they both output the same signals. BUT - I've forgotten that I implemented running status support on the MPG-200 (which means that the midi device generating the CC messages does not have to send the controller number again as long as it is the same controller as the previous one). The JX-3P on the other hand, does not support running messages, so it has to explicitly get a controller (or address as it is called in the PG-200 service notes) message for every data message. I have forgotten to implement this and instead just send the new controller value. Not a hard thing to fix, but missing none the less.

Here is a picture of my setup btw:




To the left is a macbook connected to a saleae.com logic probe, which I used to decode the PG-200 signals. The white square to the right of it is a prototype card/solderless breadboard, with all the necessary electronics (except for the microcontroller and associated circuitry) for interfacing the JX-3P. Behind that is my good old Mikroelektronika EasyPIC3 development kit, connected to a different PC (behind the synth). This kit holds the microcontroller. To the right of it, just beneath the big screen is the JX-3P, and below it is the guts of the PG-200 (the box is actually under it). To the far right is my Australian Redback edition Little Phatty which I only use as a midi controller in this setup.

Saturday, November 10, 2012

Ask google

For a while now I've been working on the MPG-200 (Midi enabled PG-200). One of the challenges is that while midi is 8 bit serial, the PG-200 runs 9 bit. Because of this, I've been trying to use a normal output pin for transmitting data to the JX-3P, while reading midi using the built-in UART on the microcontroller (PIC 18F series).

Aside from some rather ugly code, I've had some trouble getting the "bit banging" to work fast enough - I tried to send one bit at the time through an interrupt routine, but even with almost no code in the interrupt handler, the minimum delay between invocations was higher than I needed to achieve 31.25kHz transmission.

I did successfully implement a method where data was sent in one go, with NOP instructions in between bits for timing, but that takes a full 1/4000 of a second for each byte, in which time the microcontroller cannot do anything else.

So, to try to figure out how everybody else do their bit banging (...), I asked Google. The first post I found was this: http://www.embedded.com/design/embedded/4006445/Tricks-with-PICs. Here, I discovered something cool. The PIC family can actually transmit 9 bit while still receiving 8 bit! All my problems suddenly vanished :-D

The moral of the story is: Ask google, there's always someone who has done what you want to do before you :-)