Guitar to CV/gate project issue

Started by Mick Bailey, January 17, 2022, 06:08:15 PM

Previous topic - Next topic

Mick Bailey

I though it would be better to start a new thread on this, rather than tacking on to my previous posts.

Splicing together the EPE guitar to MIDI circuit with the Obsolete Technology MIDI to CV/gate is successful beyond what I ever hoped for. No code modification necessary to make the CV output sustain a note indefinitely - each new note just outputs it's respective 1v/oct voltage. Perfect for a mono synth and I can get percussive short attack/decay sounds, or very long climatic long attacks and held notes with slow and deep filter sweeps, plus anything in between. It's what I've been trying to do for the past 20 years using analogue circuits, without any success.

There's one major problem, though. Despite calibrating my oscillators again and setting up the MIDI to CV/gate for 1v/oct, there's a serious pitch error on the top E string played open - it's very sharp, as well as a slight sharpness on the subsequent F and F#. It's identical with the same notes played on the B string. All other notes are to pitch and the octave intervals from the bottom E string to the top E 12th fret are perfectly in tune. The open E voltage is 0.057v higher than it should be. Given that the voltage interval should be 0.083 between semitones, that's a pitch error of 68 Cents.

The schematics are here; https://www.diystompboxes.com/smfforum/index.php?topic=128573.0

The .ASM files are located at http://sites.google.com/site/potulfx/marketing-docs/G2Mplus.asm?attredirects=0&d=1 for the guitar to MIDI. The MIDI to CV file is in the Obsolete technology link. I'm using version Midi_CV Obsoletetechnology_v1_2_16F628A.

I don't have any device that can play MIDI directly, otherwise I would be able to diagnose if the first section is causing the problem. I'm assuming though that the guitar to MIDI is well-proven and pitches correctly, as it's been a magazine article built by successfully by a number of people. Are the individual notes determined by a lookup table, or are they calculated mathematically? I'm not grasping how just certain notes can be out of tune and I've tried three different guitars (all in tune) with identical results. I also checked the D-A reference voltage and it's spot on 4.7v.

potul

The guitar-to-midi project does not implement  pitch bends, so there is no way for it to be sharp or flat other than in multiple of semitones.

So, my bet goes for the midi to cv converter.

Do you have any midi capable audio interface in your PC? Or a usb midi cable. If yes, you can use midiox or similar to monitor, or even send midi events to the cv portion for testing.


potul

#2
So, are these 3 notes the only ones that are out of tune? That's weird.

I haven't looked at the midi to cv converter code, but maybe there is some lookup table that needs  to be adjusted for your project?

Mick Bailey

I've just done some experimenting and established the problem does lie with the MIDI to CV converter. I'm suspecting it could be the D-A conversion, because that's been problematic with an earlier code revision and the developer says this version is better, but still not perfect and would need a 12-bit DAC to give better resolution. If I adjust both the top and bottom E strings to be in tune using the trim pots for the output voltage, then other notes are out. Attempting to even out the error just moves the problem around. I did some further voltage checks and there are many other pitch inaccuracies, mostly not that noticeable with the lower strings - certainly not as far out as those three notes.

My thought is to keep the guitar to MIDI interface, but do the MIDI to CV conversion with an Arduino nano using this design; https://electro-music.com/forum/topic-71289.html. The voltages are directly referenced in a table so should be perfectly in tune. It's also possible to tune any note within the 5-octave range to a desired voltage, enabling custom tunings if desired. Arduino is new to me, but the parts are inexpensive and I managed to compile and verify the code.

I would have preferred to have got my existing setup just right, but it may make for a neater and more versatile build going down the Arduino route.

potul

The arduino option seems simple enough. And reprogramming and coding Arduino in C is much easier than using ASM for the PIC

Let me add 2 comments though:

First, if you are still willing to use your existing setup, the asm program uses a table lookup to conver to logaritmic CV. I think it would be feasible to tweak it to get a "calibrated" CV based on what you measure.

Secondly, I think it would be feasible to include the detection algorithm into the arduino, and have the whole guitar-to-CV functionality in a single device, without needing to go MIDI. The algorithm for detecting notes in the PIC is not complicated and should be possible to port it to C in the arduino.

Mick Bailey

I wondered about combining the guitar detection, but I don't have any programming skills so it would be a fair learning curve to be able to port the code to the Arduino. That would be the perfect solution, though.

With the existing setup the logarithmic CV is restricted to 3 octaves and would be too limiting, though I don't know if this could be extended. I think the Arduino route would be the easier route, even if I keep the EPE section.

niektb

Maybe I'm talking bogus but just throwing it in as food for thought. Isn't some detune expected as 1V/oct is a linear function (Just Intonation) and the guitar isn't (Equal Tempered)?

Mick Bailey

The description of the guitar to MIDI conversion is that the firmware quantizes each note to a MIDI value of that note. So the output is the same as (say) a MIDI keyboard This appears to make sense, as I can flatten or sharpen the tuning of a string by nearly half a semitone and the pitch of the output doesn't alter. The output then gets converted from MIDI to CV. I compared a list of 1v/oct note voltages to the output of the DAC and there are relatively minor differences, except for three notes. I would expect the voltages and the tuning to be the same as that for a keyboard. If those notes were corrected then the setup would be acceptable within itself (excluding any comparison with the guitar). Basically, it should sound as in-tune as my 1v/oct keyboard.

The DAC reference voltage is 4.7v and the tuning precision is 4.7/256 (8-bits), or 0.018v. This equates to a 22% possible error for any note, so two adjacent notes could be up to 44% apart - almost half a semitone. I think that's possibly where the problem arises.

Some of the Arduino parts have arrived - just waiting for the 12-bit DAC and will replace the MIDI to CV half. It will be interesting to see if this fixes everything. If not, each individual note in a 5 octave range can be tuned and stored to provide correct pitch.

niektb

Quote from: Mick Bailey on January 21, 2022, 03:58:50 AM
The description of the guitar to MIDI conversion is that the firmware quantizes each note to a MIDI value of that note. So the output is the same as (say) a MIDI keyboard This appears to make sense, as I can flatten or sharpen the tuning of a string by nearly half a semitone and the pitch of the output doesn't alter. The output then gets converted from MIDI to CV. I compared a list of 1v/oct note voltages to the output of the DAC and there are relatively minor differences, except for three notes. I would expect the voltages and the tuning to be the same as that for a keyboard. If those notes were corrected then the setup would be acceptable within itself (excluding any comparison with the guitar). Basically, it should sound as in-tune as my 1v/oct keyboard.

The DAC reference voltage is 4.7v and the tuning precision is 4.7/256 (8-bits), or 0.018v. This equates to a 22% possible error for any note, so two adjacent notes could be up to 44% apart - almost half a semitone. I think that's possibly where the problem arises.

Some of the Arduino parts have arrived - just waiting for the 12-bit DAC and will replace the MIDI to CV half. It will be interesting to see if this fixes everything. If not, each individual note in a 5 octave range can be tuned and stored to provide correct pitch.


Yeah it makes sense that the midi firmware already compensates for the equal tempered intonation... Then just disregard anything I said!

However, there is much more to a DAC than just the bit precision... Could as well be a matter of non-linearities... https://www.allaboutcircuits.com/technical-articles/understanding-dnl-and-inl-specifications-of-a-digital-to-analog-converter/
What was the DAC type? I can take a look if the datasheet gives us any numbers... :)


Mick Bailey

The circuit developer mentioned a repeating non-linearity being an issue affecting every 8th note, but it seemed to be mainly ironed out in this version. Maybe not enough, though. The DAC is an AD7528JN. The device originally specified was an MX7528JN, but I couldn't get hold of one. As far as I can see, the only difference is the manufacturer - but I could be overlooking something.

Mick Bailey

I replaced the MIDI to CV half with the Arduino and the pitch is spot-on - the voltages are all within 0.001v accuracy . It's interesting how it calibrates; C3 on the guitar would be 3v normally, but with a 5 octave range the 5v D-A converter would run out of voltage. However, when the switches are set to encompass the guitar's range, the CV drops to 1v for C3 and all the note voltages get referenced to this and are stored. If the bottom E was tuned down to C then that would be 0v - though the guitar to MIDI section won't detect that low. The MIDI notes responded to are also set to the correct octave range.

Whilst the guitar side is a little glitchy and there's some latency, overall it's a lot better than I would have expected. I added a linear portamento control to one of the buffered CV outputs and there's an unexpected bonus - the hammer-on feature does bends. When I bend a note, the hammer-on setting plays each semitone increase in sharpness as an individual note, but just a little portamento smooths them out into a continuous bend. The only thing is that the bent string needs re-plucking before releasing back, otherwise the level drops too low for detection.



ElectricDruid

Quote from: Mick Bailey on January 21, 2022, 03:58:50 AM
The DAC reference voltage is 4.7v and the tuning precision is 4.7/256 (8-bits), or 0.018v. This equates to a 22% possible error for any note, so two adjacent notes could be up to 44% apart - almost half a semitone. I think that's possibly where the problem arises.

A 8-bit DAC *could* be used for a job like this. After all, if you're doing five octaves of notes, you only need 61 values, so even a 6-bit DAC would be enough (64 values, 0-63). However, the DAC would have to be tuned to give 83.33mV steps (1V/Oct). That'd need a 5.16V reference for the DAC ideally. And the DAC needs to be accurate, since for an 8-bit DAC, even +/-1LSB would be 25 cents out, massively audible.
Incidentally, the Sequential Pro-One monosynth works exactly like this, using an 8-bit DAC, and ignoring the lowest couple of bits.

Anyway, all that is an aside, really. Glad to hear you've got it fixed with the Arduino MIDI-CV, and I hope the next steps go ok too.

potul

Quote from: Mick Bailey on January 22, 2022, 12:34:10 PMThe only thing is that the bent string needs re-plucking before releasing back, otherwise the level drops too low for detection.
I was the one writing the hammer-on detection. I don't remember exactly how this was done, but I can review and check if this can be improved.

potul

I just checked the code, and the way it works it that if it detects a change in pitch (quantized to semitones) it sends the current note off and start a new note. So it's expected that any bend will trigger a new note in semitone steps.
As long as the amplitde of the note is enough it should also track bend down. But if the note is fading, it will not detect the new pitch.

So, not  much room for improvement in the code for your "bending" feature.

Mick Bailey

I've given this some more thought and probably the best way to implement smooth bends overall is to use an expression pedal patched to the synth's oscillators CV inputs. This would also give the flexibility to go from slight blues bends to Whammy pedal style pitch changes, depending on how the CV level is set and not require protamento to smooth out the semitone intervals.

A question I have is the lower notes seem to have more latency than the upper ones, which have very little latency. My understanding is the frequency detection is fixed at roughly 12ms (one complete cycle of a low E vibration). This would suggest that the latency would be the same for all strings - is there something else at work that causes this?


potul

Hi, the algorithm works more or less like this:

1-Sample signal during 12ms and determine max and min peaks. Note that the sample is not stored anywhere due to memory limitations.
2-Calculate a max and min tresholds based on previous max and min peaks (subtracting some offset)
3-Sample again the signal and wait for the value to change from a peak to a valley, and back to a peak (comparing with the max and min thresholds). Timeout if no detection is done properly after around 12ms.
4-Use the timing information to calculate the note.

So as you can see, although step 1 takes always around 12ms, step 3 depends on the lenght of the wave. The longer the period, the longer it takes to see the transition to happen.

In a more powerful device what we could do is sample only once (12 ms) store the data, and then do all calculations with the sample stored in memory. But in this case, we need to sample at least twice  (once to get the amplitude, and a second sample to get the frequency).


potul

Quote from: potul on January 27, 2022, 09:29:26 AM
Hi, the algorithm works more or less like this:

1-Sample signal during 12ms and determine max and min peaks. Note that the sample is not stored anywhere due to memory limitations.
2-Calculate a max and min tresholds based on previous max and min peaks (subtracting some offset)
3-Sample again the signal and wait for the value to change from a peak to a valley, and back to a peak (comparing with the max and min thresholds). Timeout if no detection is done properly after around 12ms.
4-Use the timing information to calculate the note.

So as you can see, although step 1 takes always around 12ms, step 3 depends on the lenght of the wave. The longer the period, the longer it takes to see the transition to happen.

In a more powerful device what we could do is sample only once (12 ms) store the data, and then do all calculations with the sample stored in memory. But in this case, we need to sample at least twice  (once to get the amplitude, and a second sample to get the frequency).


Another thing to consider is that the code is not very optimized and step 3 can take up to 2 full wave cycles, depending on when we hit the signal. So in the worst case, for a low E note we could have a latency of around 36 ms.

Mick Bailey

Is it feasible to re-order the detection algorithm to improve the latency? I'm thinking that if the note calculation is done first, then the MIDI note could be output could be followed by the amplitude detection. I was thinking that the amplitude detection would still be valid even if this was done quite a few ms after the initial not pluck and would only be used for comparative purposes to detect whether a new note had been plucked. The velocity associated with each note would need to be a default value, but in the case of old-style mono synthesis there's no velocity information required, (every note is equal) - just the  corresponding CV and anything else is ignored by the MIDI to CV conversion.

The process could be in the order of: 3,4,1,2.

potul

Nope, it cannot be done with the current algorithm. The pitch detection uses data from the amplitude detection algorithm, so amplitude must come first. Maybe the algorithm could be rewriten to do both concurrently, that's something that deserves a spin.



Mick Bailey

Does the timeout feature have any bearing on latency? The original article describes it as:

"With all software applications, there is a chance that something in the outside world will not respond in the way that the software expects.
In this case, when playing a series of quick notes, the situation can occur when the guitar note suddenly ends while the software is trying to time between two peaks.
The routine would keep waiting for the missing peak and only find it when the next note is played, by which time the calculations would be wrong. Eventually it would correct itself by another similar mistake! So, it was decided to include a 'time out' option that would make the routine end and wait for a new note if the this perceived note wavelength was longer than 20mS (well load below bottom note). This solved the problem."