Guitar-to-MIDI project article

Started by Mark Hammer, November 02, 2009, 01:07:26 PM

Previous topic - Next topic

potul

Let me try to answer some of your questions and give my  2 cents....

-Bass:

I think this was discussed some posts before in the same thread...
The original project is designed for guitar and will not track the lower notes on a bass. This is due to the fact that the PIC reads only 12ms of data trying to find zero crossings. 12 ms is not enough for bass guitar (a typical 4 strings bass goes down to 41Hz). So you will need to increase the sampling time to at least 24ms or more. In addition, you will need to modify the note_table and review the piece of code in "MIDINOTE", probably it needs some adjustments.
As you will be doubling the sample window, you will have some more latency. Maybe some optimization could be done here to avoid it.

-Polyphonic

This has also been discussed in the past.
Having the same interface 4 times and then mix the MIDI signal looks overcomplicated. I would rather go into building a completely new project reading 4 ADC in parallel in the same PIC.  PIC 16F88 has up to 7 Analog pins, and it can run up to 20Mhz wiht an external cristal, so in theory you could read 4 ADCs and do the note detection in parallel and you would still have free cpu cycles. (the original project runs at 4Mhz)

Of course, this would require a major re-coding of the project... almost start from scratch.
On the other hand, you will need a quadraphonic pickup to get the signal of each string separately.

-Read Slides:

I did a modification to the software that allows for reading slides in the guitar. It only works in steps of semitones, so it does not work for bends, tremolos, etc... You have the modified code somewhere in the thread.
If you want to go beyond this, it gets very tricky. I recoded the whole thing trying to get bends to work and I didn't succeed. I think the algorithm has some limitations and it does not detect accurately enough to be used this way.
If I would start a similar project now I would probably go using a more powerful dsPIC, and use some kind of autocorrelation or combined autocorrelation with FFT tecniques.
I haven't looked at the theremin project, but looks interesting. If your problem is the note-off, you need to define how the device will determine when to send a note-off.
What you can do is send a note-off when sound amplitude goes below a threshold, or when a new note is detected.


-Modulation:

Same as above. If you want to detect vibratos, etc... you need to have a better detection algorithm.

My general advice is to consider that this project has some limitations, but it does what it does reasonably well. But if you start adding requirements to it, it's probably better to start from scratch using more modern DSP techniques.

I hope this will be of some help.

Regards





Diodac

Buddy Potul
Thank you for your answer helped me a lot.

I'd like to do is my dream, but the lack of a knowledge base to adapt the code to the bass as well as the usual guitars and even at 4 or 6 independent ADC.

My thought with 4 independent circuits and MIDI merge results from a "go shortcuts" because they do not have to modify the code, but the idea that a single processor can be done is wonderful.

Already stop to such rarities as the detection bending, slides, tremolos etc. :)

The option to use dsPIC good but out of my reach, at least for now: - \
FFT and autocorrelation solves many of the problems I think.

G2M regards the improvement could be used, for example, filters, or other solutions.
I tried, Smith Tigger from the Tom Scarff, I connected directly to the input PIC16F88 improved some problems with overlapping harmonics but there are new ... do not read high tones correctly. Similarly, when I used the Delta-Sigma modulator input before TL072.
 
Anyway, still looking for the optimal input interface, because it determines the major part of the success.

Potul please help me with made ​​into G2M on poly-bass, or at least mono B2M :)? I'll take care of finding the perfect harmonic filter and the input.

With modulation I thought to do a trick involving the use of the frequency to voltage conversion and adding some simple ATmega168 uC that will send control change messages or something. I used to do another project where I used this trick can up that will do it in G2M

Today, many have tested the system by Tom Scarff Pitch2Midi. I know that you Potul you checked it too. It would could do to the guitar. It reads good tone, quite resistant to less clean strum. I was so impressed, copes with bass guitar and solo .. I try to reach as Tom defeated the problem of 24ms and passing through 0 - reads the entire range of tones! But the defining the end of the amplitude is poorly done because it takes an awfully long time. Maybe to do as the G2M is a project of Tom would be something really good. Maybe a way to detect new note will be a better solution?

Potul you could fix it in a project of Tom?




Project Stephen - I sent you email something to the watch :)

Best regards

potul

I've been digging into the project to see how difficult it would be to adapt it to bass. I think that only by changing some numbers you can achieve it.

First of all, we must expand to 24ms the timing for note peak detection in lin 204 change 2 by 4

;--- WAVEFORM PEAK LEVEL DETECTION FOR 12MS ---

PEAKS
CLRF PEAKH
MOVLW 255
MOVWF PEAKL
MOVLW 4
MOVWF DELAY1


Now we need to increase as well the timeout threshold for frequency detection in the TIMING routine. This is done by changin "BTFSC    TMR1H,5"  to "BTFSC TMR1H,6" in all 4 occurences. This will double the time to wait until failure.



;---- MEASURE TIME FOR ONE WAVE, BETWEEN PEAKS -------
 

TIMING CLRF TMR1L
CLRF TMR1H

T1 BTFSC TMR1H,6
GOTO TERROR
BCF MARKER,3
CALL ADC
MOVF TRIGL,W
SUBWF ADRESH,W
BTFSC STATUS,C ;IS ADRESH - TRIGL +VE IE CARRY SET?
GOTO T1 ;NO, SO RETEST UNTIL IT IS

T2 BTFSC TMR1H,6
GOTO TERROR
CALL ADC
MOVF ADRESH,W
SUBWF TRIGH,W
BTFSC STATUS,C ;IS ADRESH - TRIGH +VE IE CARRY SET?
GOTO T2 ;NO, SO RETEST UNTIL IT IS

CLRF TMR1L
CLRF TMR1H
NOP

T3 BTFSC TMR1H,6
GOTO TERROR
CALL ADC
MOVF TRIGL,W
SUBWF ADRESH,W
BTFSC STATUS,C ;IS ADRESH - TRIGL +VE IE CARRY SET?
GOTO T3 ;YES, SO RETEST UNTIL IT IS

T4 BTFSC TMR1H,6
GOTO TERROR
CALL ADC
MOVF ADRESH,W
SUBWF TRIGH,W
BTFSC STATUS,C ;IS ADRESH - TRIGH +VE IE CARRY SET?
GOTO T4 ;NO, SO RETEST UNTIL IT IS

BCF T1CON,0 ;STOP THE TIMER TO RETRIEVE THE DATA

MOVF TMR1L,W
MOVWF LOBYTE

MOVF TMR1H,W
MOVWF HIBYTE

BSF T1CON,0 ;RESTART THE TIMER
RETURN

TERROR
BSF MARKER,3
RETURN




Now we need the code to compute correctly the octave (original code cannot go below note 35 and we need to go down to 28). This is achieved by changing 2 things, on one side we have to change the octave offset in line 239. Change 48 to 60


;----- GET MIDI NOTE FROM FREQUENCY TIMING ----------

MIDINOTE  BCF MARKER,1
MOVLW 60


And the last change is we need to decrease all numbers in NOTE_TABLE by 12.


;------ MIDI NOTE DATA TABLE ----------

NOTE_TABLE ADDWF PCL,F

DT 35,35,34,34,34,34,34,34,34,33
DT 33,33,33,33,33,33,33,33,33,32
DT 32,32,32,32,32,32,32,32,31,31
... etc....



I haven't included the whole table, you should be able to do the math on your own, it's only subtracting 12 to all numbers.

I haven't tried it, but on paper it looks like this should do the trick and give you one lower octave of range.

Give it a try and let me know.

Mat


potul

Quote from: Diodac on November 26, 2013, 05:58:40 AM

I tried, Smith Tigger from the Tom Scarff, I connected directly to the input PIC16F88 improved some problems with overlapping harmonics but there are new ... do not read high tones correctly. Similarly, when I used the Delta-Sigma modulator input before TL072.

If I recall it correctly, it is not needed to add the smidth trigger to our G2M and it will deliver low value and degrade the velocity sensing. This was needed in Tom Scarff project because he was using a digital input for frequency measuring, and a separated analog input for amplitude. In G2M project, we just use an analog input and do the equivalent to the smidth trigger via software.


Diodac

Mat double thank you :) Done. However, I do not know what the conversion to Intel 32 hex file 90kb it weighs too much. Programmer crashes that message above the permissible size for 16F88
What could I have done wrong .. after all it's a breeze : - \ so glad once I play the bass midi : (

It gives the code for inspection by interested : https://drive.google.com/file/d/0B54jdI_xntNTVWg3ZGFPR0xaMnc/edit?usp=sharing


Maybe someone here will convert and throw good hex : D and now I still will search for my mistakes.

Regarding the draft Tom Scarff , I know that do not need Shmidth Tigger , etc. I tried what happens and what the effect will be.
 
To our will need a good filter but it experimentally  we must choose.

I am very intrigued the design by Tom, if in some way to improve the detection of the end of the amplitude, I have an idea how to do it all in one digital filter harmonics and Shmitd Tigger for the digital input from in audio.

I still want to do the project by Stephen,  another G/B2M :)
because those give you the ability to detect bending, etc.

It's fascinating to find the best way to unique B/G2M we have to try everything.
Regards Ark

potul

The file looks good.

Just to be on the safe side.... did you compile it before trying to send it to the PIC?   8)
If yes, what compiler did you use? Standard MPLAB?

Diodac

Yes I did compile before sending. Almost got tears in my eyes : - \ I'm using MPLAB IDE v8.43, v2.40 PICkit programmer.

I still do not go, maybe a newer version of the compiler help?

potul

Just in case I will compile it and send it to you. As I have always a virtual machine configured for MPLAB it will take 5 minutes.
I will send it via email.

Mat

potul

Done it.
You should have it in your email... :)

Give it a try and let us know. Once you verify it works we can add the slide/hammeron/hammeroff tracking code from my modified G2M and see if it works.

Mat

Diodac

I have to set everything, but something tells me that I need to bring an old computer out of my garage on back to main work. There on XP it was all good: D

Mat do not know how I return the favor you for your help :) WORKS with my bass :) also continue to work with the guitar!
I am more than happy that so
I think we can go ahead with the project. Make new things tracking slides.
After the first tests, I conclude that it is really OK, bass guitar does not do much problems as it was in version G2M even with the guitar. Circuit has become somewhat more resistant to the harmonic and sloppy strumming a guitar solo as well. What surprised me positively. Now I take to be the filter.

The only thing we can somehow improve at least a minimum response time to new note? Where should I try?
Even if not it's still a very good result:-D


You know, I keep thoughts of the polyphonic bass I am, look at the code and wonder how to go in this direction.

potul

I'm happy to see it works.

Regarding the response... do you mean that there is some lag between your string pluck and the MIDI note being sent?

I guess this has now got worse because of the increased "listening" timing to accomodate for bass wavelength..

Looking at the code... I guess something could be done to improve this, because now I think it first detects amplitude, and only when it decides there is a new note, it starts tracking pitch. This adds some delay that maybe could be reduced. I will think about it...

Diodac

Great, I'll be thinking and go tests in the direction of the optimal filter harmonics :D

potul

I took a deeper look at the code during luch break...
I see that part of the latency is due to the uneffective algorithm used. Let me explain more or less what the PIC is doing:

-Monitor ADC during 24ms. Register min and max values and compute amplitude based on this. Compute positive and negative triggers (these will be used to compare with signal and find if we are in a peak)
-If a note is detected, start reading ADC again and wait for a negative peak (comparing with the trigger).
-When a negative peak is detected, wait for a positive peak. When this is detected, it means we just transitioned from a negative to positive peak, and we start counting time.
-Repeat the wait for negative-wait for positive peak again. When the second positive peak is detected stop the timer.
Now with this time measured we can compute the frequency and midi notes.

The issue is that the first step of detecting amplitude takes already 24ms, and the pitch detection for a low E can take between 24ms and 48ms depending on the point of the wave we are when we start measuring. This can be a worst case of 70ms latency plus some added lag due to computation.

Theoretically we can shorten this simply by having a smarter code. I.e, if we don't wait always for a negative peak to positive peak to start the timer, and we simply look for whatever transition, this can reduce by 12ms the max latency. And we might be able to find a way to do the amplitude detection at the same time we do the frequency measuring... but this would require some thinking, as in the pitch detection we use the amplitude found in the previous step.


potul

Going back to things... I've adapted the G2MPlus to Bass as well. I'm sending you the hex file via email.   8)
It should be able to track slides/hammer-on/hammer-off now. (note that hammer on-off of more than 5 frets will not be tracked, but this can be modified in the code if needed)

In order to use the new feature, you need to add an extra switch to the PIC. The program is reading RA1 (pin 18), if it finds 5v is uses the slide/hammeron, if it reads 0v it will stay "classic" without tracking slides.
If you don't have a switch, just stick 5v to RA1 with a jumper to test it.

Mat

Diodac

B2Mplus tested , and I have some thoughts on what we can do  :icon_biggrin:

1 Slides, hammer on / off 5 thresholds think as we increase will give us a better effect of liquidity in playing . We can pick up about 100% ?
Now with 5 begins to react well to bending , etc. I think that as we raise will be even better. We have to check it out .

Then we can attempt to a trick , namely to obtain the most realistic bending , etc. moreover, we need to introduce additional reading next ADC and sending from CC messages . Reading frequency and calculation , hammer on / off just as we have done, but must convert to CC # 1 0-127 , no note on / off .

This will allow us to get I think the most realistic reflection of the audio signal from the guitar .
Sometime in other audio-midi project taken at the Arduino platform I used a similar trick I used this with CC # 1 and it worked well. Only there did 0-5V input to the ADC and here we have to do reading frequency and amplitude.

2 Now I kind of shifted in time
Delays detection and delayed the end of how hold function, even when immediately after striking dampens the strings. As if that is not the resistor, because I use ok.330k

Smarter code , reduce the time from 24 to 12 ms and the way to look at any of the transition and the amplitude of this idea very well. We should try to achieve it.


3 Programming sustain / hold function similarly run like a hammer .
I think it should work in the following way , it keeps the detected note and the amplitude drops to a low , goes to detect the next .

See here http://www.instructables.com/id/Frequency-Detector-using-PIC-12F683-Processor/?ALLSTEPS its a very useful and helpful article to our idea of ​​B2M

Ok I'm going to test and optimize the harmonic filter  :icon_twisted:

potul

Quote from: Diodac on November 28, 2013, 05:37:25 AM
1 Slides, hammer on / off 5 thresholds think as we increase will give us a better effect of liquidity in playing . We can pick up about 100% ?
Now with 5 begins to react well to bending , etc. I think that as we raise will be even better. We have to check it out .
This will not work. This is not how the code works... 5 means you can only hammer-on notes separated by 5 semitones. If you increase this number you will only be able to do hammer-ons with higher intervals, but it will not improve accuracy, in fact it will probably get worse. This is the reason I added this limit, to avoid octave jumps and similar.
On the other hand, bending will be detected as it is now, but only in full semitones steps. The code is going to resolve always to the closest midi note, but no bending info will be sent. This means that if you do a bend, the note will change in steps, not smoothly

Quote
Then we can attempt to a trick , namely to obtain the most realistic bending , etc. moreover, we need to introduce additional reading next ADC and sending from CC messages . Reading frequency and calculation , hammer on / off just as we have done, but must convert to CC # 1 0-127 , no note on / off .
This will allow us to get I think the most realistic reflection of the audio signal from the guitar .
Sometime in other audio-midi project taken at the Arduino platform I used a similar trick I used this with CC # 1 and it worked well. Only there did 0-5V input to the ADC and here we have to do reading frequency and amplitude.
The issue is not sending note-off/note-on or sending CC messages for bending. The issue is that this algorithm with this PIC is not able to accurately detect bends. If you want to detect bends (and go below the semitone resolution), you need to start from scratch. I'm not saying it can't be done using this PIC, but code must be rewritten and probably we would need to increase operating freq to 20Mhz with an external crystal.

Quote2 Now I kind of shifted in time
Delays detection and delayed the end of how hold function, even when immediately after striking dampens the strings. As if that is not the resistor, because I use ok.330k
I don't get the point...What is the issue here? that the note is ending too early?

potul

Quote from: Diodac on November 28, 2013, 05:37:25 AM
See here http://www.instructables.com/id/Frequency-Detector-using-PIC-12F683-Processor/?ALLSTEPS its a very useful and helpful article to our idea of ​​B2M

Oh, I forgot to mention. The article you linked is interesting, but will not work for us. I already went down this road some time ago....
The Goertzel agorithm that is used in this article is used to detect a concrete frequency in a signal. In some way, it is like doing an FFT only for one bin instead of the full spectrum.
It could be used maybe for a tuner or similar, where you have a target frequency you want to detect, but not for a pitch tracker.

According to my knowledge after reading multiple articles here an there, for monophonic pitch detection nothing beats autocorrelation derived methods in terms of accuracy. But... you need a lot of calculation power and big samples.
An interesting autocorrelation based method is SNAC. Take a read at this link if you are interested in the topic:  http://www.katjaas.nl/helmholtz/helmholtz.html

In the frequency domain, Cepstral analysis seems to work fine as well, but I've never tried to use it.

Anyway, neither autocorrelation nor FFT analysis are in the ballpark of what we can do with this PIC, so we need to stick to zero detection unless we want to jump into more powerful uC.


Diodac

OK not touch the hammer this time  perhaps.

I'd tried to pick up the PIC into 20Mhz and we introduced modifications to the code as far as you like. It will surely make this project very special. I am also willing to migrate up here if the can not. But it seems to me that the PIC can suffice if the to conquer into 20Mhz and improve our algorithm, add the filter and the idea that I described in the email.
I hope ..
Migration is a big job looks but why not in the future  8)
QuoteI don't get the point...What is the issue here? that the note is ending too early?
I mean it's too late finishes but the value of the capacitor gave, 22pF and 250k resistor. It helped.
Start delay are for obvious reasons 24ms etc.

I'm sorry that sometimes my words are difficult to understand English is my second language.


Article that you offered promises to be very interesting. SNAC seems that it must work well.

Diodac


I made some tests to safely B2Mplus and another more specific thoughts I have.
Test without a low pass filter :
1 Shades shoots each time there is no problem unless they come to the front overlap harmonics.
2 Hammer lightly not keep up - the reason? too many components in the sound , requires a filter , skipping the code we need to do a little intelligent .
3 Reading the key long - as above, the signal has to be filtered is somewhat shorten the time and improve . And then we should try to read it at 12ms .
4 And the most painful problem of uneven and too late detection
plucking and jerking strings - filtering can help a little .
Ideas for improvement :
Pick a few filters, today I started the bread board , tests and will continue all weekend. Later I will write here what has improved and will add schematic of the applied solution .
I think we should also browse the code relating to the problem of 24ms and especially the detection of plucking the strings .
Already at the beginning can we put an external crystal 20Mhz for our future expansion.
This time I'm looking for a good solution to the LPF and I will inform about the progress .

Diodac

#159
As promised , B2M tests done. I tried the bass and solo . For clarity, 90 % of the problems of overlapping tones appeared in the " hammer on" in normal mode B2M is delayed reading pitch and

plucking .

I wanted to solve the problems :
- Overlapping tones.
- Delays and errors occurring during rapid plucking the strings , etc. .
- Delay reading the key .

Use less intelligent filter LPF 2 and 4 in a row, composed of op-amp type TL074 , LF347 or TL084 little help I would say even more hurt when B2M worked in " hammer "

In the next weeks the tests carried out with an intelligent filter LTC1065 . During testing, I came to the conclusion that a positive result can be achieved through the use band equalizer that

tomorrow I will try to check .

Therefore, it attempts to apply the active filter did not help , I watched the whole arrangement again and decided to rearrange something .
In place of the TL072 which I put TLC272 works well in 5V and has better performance for this project. In addition, R2 replaced the potentiometer 1M. Smooth adjustment resistance was very helpful,

because it allowed exactly set the input level to the PIC.

I turned on everything and came to the expected result. There have been improvements.
In the "hammer" and normal and bass guitar.
- Significantly minimized the problem of overlapping tones.
- Improved reading speed tones
- A much faster process picking.

The need to accurately determine the input level to get equilibrium. Because the large entry level picking good but overlapping appear.
After connecting a guitar solo and change the level of the input signal using a potentiometer was also a significant improvement.

When working with a guitar solo here, you can apply the filter:

https://drive.google.com/file/d/0B54jdI_xntNTY0RxQ1poVGM2ZGc/edit?usp=sharing

Plug in directly to the input.
Op-amp - TLC272 powered symmetrical + - 5V

This filter helps in B2M with a guitar solo. Makes B2M becomes universal. Much eliminates overlap of tones. Use only with a guitar solo.

Did not check this filter with a classic G2M, and a guitar solo but there also should help. With free time G2M check the filter and write what happened.


Overall, I'm glad I improved design for my needs. Check yet LTC filter as it will work.

As regards the improvement of code:

I think we need to try the method of 12ms for B2M and any other convertion. Not to count everytime anew just looked in. Mat knows how to do it :)

Mat if you found moments of time that would be great.

When we improve everything we can then think of other modifications.


I think it's almost good, improved code that will do almost perfect 8)