CLeJack / Scribe

Guitar to MIDI
9 stars 0 forks source link

Midi Bends Changes list #8

Open CLeJack opened 3 years ago

CLeJack commented 3 years ago

Adding pitch bend would look something like this.

Add the following: Editor and Processor Changes


DataModel Changes


MidiSwitch / State Machine Changes



The flow of data is all controlled within the function ScribeAudioProcessor::ready


rikamusik commented 3 years ago

hello charles, I tested the pitchbend branch today an it starts to send pitch bends, nice one I had to add case MidiState::bend : output = on(params); break; in midiswitch.cpp to get out of the bend loop

I really don't know if it was the right thing to do, but it helped me explore it more

I realized that the real midi specs for pitch bend are -8192 to 8192 if we send note = juce::MidiMessage::pitchWheel(1, 0); then qmidiroute sees it as -8192 if we send 8192 , then it shows 0 (centered)

so I tried to send it like this: note = juce::MidiMessage::pitchWheel(1,( 8192 + (8192 (0.5 calcs.pitchWheelPosition + 0.5))));

I was wondering why the 0.5 in note = juce::MidiMessage::pitchWheel(1, 16383 (0.5 calcs.pitchWheelPosition + 0.5));

another thing I realized, is that ardour vst3 support seems to ignore pitch bends (ardour 6.5) but if I load it with carla , it works

how do you test it ? the only way I found to see my std::cout appear is to make a standalone version

thanks for the hard work

rikamusik

CLeJack commented 3 years ago

Hey Rikamusik,

I think I'll have to make one more test file tomorrow to finalize things to see if I can get as close to perfect as possible, but you can pull the latest changes on the pitchbend branch to get a implementation that's somewhat functional.


With respect to your specific questions:

Bend Loop issue - this should be resolved since I have a state handling the bending sequence now.

midi spec pitch wheel range - Where are you looking for this info? I don't have the official spec sheet, and I haven't really dived into midi too much, but my search results seem to show the center value as 8192. Aren't all midi messages unsigned ints?

The pitch formula calcs.pitchWheelPosition outputs values between [-1,1]. Focusing specifically on the values [-1, 0, 1] for the moment:

If you did want to have the range [-8192, 8192], use:

note = juce::MidiMessage::pitchWheel(1, 8192 * calcs.pitchWheelPosition);

Ardour - Unfortunately, this one is beyond me. Once you get to the layer of how the vst3 wrapper really works, I'm clueless. I would guess this happening somewhere between Juce's implementation for creating a vst3, or ardour's implementation for reading one. On this end, the only thing that's ever really touched is the juce pitchWheel function and the (midi) addEvents function.

testing The process is a bit involved, but I fixed the test file and it should work for you. It was built in ubuntu, and I'm currently running it on WSL.

If you navigate to Scribe/Source/test, you can run the command ./compile in the terminal to compile Test.cpp into test.o Then of course ./test.o can be used to run whatever csv you point it to. The output is generated at Scribe/Source/test/output and points to a lot of parameters used to make scribe work.

Test.cpp is currently pointed to "Scribe/Source/test/input/bend.csv," but this can be changed to any file you want at line 16 in the importCsv() function.

The csv is generated by converting a 16 bit wav file using python (see analyze.py in Scribe/python; use the function signal_to_csv) The Pandas module is needed.

At the top of Test.cpp there is the macro #define PRINT = 1. Change this to 0 if you want to stop Scribe from generating a diagnostic csv, and you can also std::cout whatever you'd like at this point.


Parameter additions

Currently there are two new parameters that are active but not attached to the gui. They can be manipulated if your daw allows you to access them.

pitch bend on: is a bool that chooses whether you want to allow pitchbend at all pitch bend threshold: is a metric that helps determine when to release pitch bending--lower values make the release faster

I estimated .06 to be a decent number for this, but sometimes the pitch bend state will hold on when you play fast, and new notes will not send midiOn messages.

rikamusik commented 3 years ago

Hello charles, I finally had the time to test today, It works, but I found that even bending my guitar string much calcs.pitchWheelPosition would mostly be under 0.1 more like 0.0273437 0.0378397 0.040506 and the pitchweel value would not go very high

so in PluginProcessor.cpp , I tried to multiply calcs.pitchWheelPosition per 10 to see what would happen

  int BendFinalVal = 16383 * ( 0.5 * (calcs.pitchWheelPosition * 10 ) + 0.5 );

    if ( BendFinalVal > 16383 ){
        BendFinalVal = 16383;
    }
    note = juce::MidiMessage::pitchWheel(1, BendFinalVal);

and it follows my guitar very good

I set zynaddsubfx so that the pitchwheel is set to 100% of a semitone

I guess that the most practical way would be that the multiplier is a user accessible float, so that anyone can tune it to its needs depending of which virtual instrument one controls

anyway it works very good

thanks again for this wonderful project

rikamusik

CLeJack commented 3 years ago

Good to hear it's working out for you. I added sliders for pitch sensistivity, pitch scaling (which you most recently requested), and a button for toggling pitch bending. They are all attached to the gui now.

For now I think I will leave this as a separate branch.

I have a few things I would like to do to improve the pitch tracking. I'm hoping to get it more accurate than any other software, figure out a way to implement better bending tracking, then move on to polyphony, but this is all some ways down the line.

Let me know if anything breaks. When I added the scaling I noticed that the notes would get stuck at 100%, but I can see that's because my system was already tracking the pitch bending decently, so any scaling would always cause it to max out. The fact that this is behaving differently with your guitar/setup is somewhat worrying, but everything will be put under a microscope as I move this to the next phase.

rikamusik commented 3 years ago

hello charles,

Here is a patch that puts the *bendScaleP multiplier at the right place, it also resets the pitch on a new note because it was getting stuck, it works really good in my tests

I changed int bendFinalValue = bendScaleP 16383 (0.5 calcs.pitchWheelPosition + 0.5); to: int bendFinalValue = 16383 (0.5 ( calcs.pitchWheelPosition bendScaleP ) + 0.5);

I attach the zip file, it has crlf line endings.

pitchbend.zip

thanks a lot

rikamusik

CLeJack commented 3 years ago

Nice catch! The patch has been applied to the pitchbend branch, and I appreciate the fix. It's working much better on my end as well. Not sure what I was thinking with my previous submission.

Have you been messing with the P. sens(itivity) parameter? If you have, what value are you using? With the current allowed range, I think it might be kinda confusing.