Kara-Moon Forum
March 28, 2024, 05:12:18 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: You can go back to the main site here: Kara-Moon site
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Plectrum and RTime  (Read 4229 times)
sciurius
Sr. Member
****
Posts: 443



« on: February 11, 2021, 01:43:39 PM »

The test program:
Code:
RndSeed 1

Begin Plectrum
    Voice NylonGuitar
    Sequence { 1.0 0 6:90 ; 2.0 0 6:90 ; 3.0 0 6:90 ; 4.0 0 6:90 }
End

Plectrum RTime 0

 90  Am * 4

This produces MIDI commands:
Code:
        ['note_on', 0, 15, 40, 90],
        ['note_on', 192, 15, 40, 0],
        ['note_on', 0, 15, 40, 90],
        ['note_on', 192, 15, 40, 0],
        ['note_on', 0, 15, 40, 90], 
        ['note_on', 192, 15, 40, 0], 
        ['note_on', 0, 15, 40, 90],
        ['note_on', 192, 15, 40, 0],

When I change RTime to 1, this becomes:
Code:
        ['note_on', 0, 15, 40, 90], 
        ['note_on', 192, 15, 40, 0],
        ['note_on', 1, 15, 40, 90],
        ['note_on', 190, 15, 40, 90],             #     <== note_on after note_on
        ['note_on', 1, 15, 40, 0],                #     <== note_off too soon
        ['note_on', 192, 15, 40, 0],              #     <== note_off after note_off
        ['note_on', 0, 15, 40, 90],
        ['note_on', 192, 15, 40, 0],

I seem to recall there was code in place to avoid notes being stopped too soon due to RTime. Did anything change?
Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #1 on: February 11, 2021, 04:52:19 PM »

And for today's homework assignment Smiley

In patPlectrum there are 2 calls to midi.addNoteOnToTrack(). This is part of the original plectrum code. Also, this call is only made from patplectrum.

To start a note vibration, this is called in line 714 of patPlectrum. The RTIME setting is passed at this point, and the actual value is calculated in addNoteOnToTrack() ... and NOT saved.

I think that to do it properly, one would need to do a bunch of rewriting and save the random values for each note and then do some comparisons on the saved values when turning off the strings. This was never done before and would be a significant bit of code, I think.

I'm not sure why this is a problem, unless you are using very short durations. You should have 364 ticks between on and off in your example and rtime is only adjusting things by one tick.

Are you reading the output correctly? Duplicate string detection might be the problem?
Logged

My online life: http://www.mellowood.ca
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #2 on: February 11, 2021, 06:45:40 PM »

Opps, 192 midi ticks for a 1/4 note ... don't know where 364 came from Smiley
Logged

My online life: http://www.mellowood.ca
sciurius
Sr. Member
****
Posts: 443



« Reply #3 on: February 11, 2021, 09:00:43 PM »

Code:
        ['note_on', 0, 15, 40, 90], 
        ['note_on', 192, 15, 40, 0],
        ['note_on', 1, 15, 40, 90],
        ['note_on', 190, 15, 40, 90],             #     <== note_on after note_on
        ['note_on', 1, 15, 40, 0],                #     <== note_off too soon
        ['note_on', 192, 15, 40, 0],              #     <== note_off after note_off
        ['note_on', 0, 15, 40, 90],
        ['note_on', 192, 15, 40, 0],

I'm afraid I don't misread this. When I feed the MIDI to e.g. fluidsynth I can hear the third note being cut off immedeately.
Strangely enough, Timidity sounds as intended...

The problem does not seem to occur for positive displacements, e.g. RTime 0,2.

Attachment contains the midi and the wav as produced by fluidsynth.

* x.zip (1299.89 KB - downloaded 151 times.)
Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #4 on: February 11, 2021, 10:35:39 PM »

I ran your example file and one I modified a bit.

Just to confirm what it is doing: It's playing an 'A' on string 6 on beats 1,2,3,4 for 4 bars.

So, there is a sort-of-bug. Here is the problem Smiley

If rtime is set then midi.addNoteOnToTrack() gets the current offset PLUS a random value. This value can be positive or negative. If we are on beat 1 there is code to never set the time before the beat, but if it's in the middle of the bar it can push either way.

And, that is where your Off precedes On is coming from.

So ... if we modify the code at line 605 in midi.py to read:

 
Code:
   # Start offsets

        zeroOffset = getOffset(boffset, 0, 0)
        onOffset = getOffset(boffset, startRnd, endRnd)
        if onOffset < zeroOffset:
            onOffset = zeroOffset
    # ON/OFF events (off is on with v = 0)

we force the off to always be past on, I think.

Do you want to try this and if it works I'll code it more efficiently. The problem with this is that Plectrum Rtime will never start a note early Smiley

Logged

My online life: http://www.mellowood.ca
sciurius
Sr. Member
****
Posts: 443



« Reply #5 on: February 12, 2021, 07:45:05 AM »

Isn't this basically the same are RTime 0,x? I use this as a workaround.

I suggest not to apply your fix for the time being. First, I'm convinced I'm the only person in the world doing these stupid things and I have a workaround. And second, everyone uses Timidity and won't notice anyway.

The correct fix would be that the note_off of the sounding string gets the same displacement as the new note_on.

Interesting side note: My MIDI::Guitar module (https://github.com/sciurius/perl-MIDI-Guitar) does it right. Probably by accident  Grin.
Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #6 on: February 12, 2021, 04:19:51 PM »

Isn't this basically the same are RTime 0,x? I use this as a workaround.

Yes (assuming x is positive).

Quote
I suggest not to apply your fix for the time being. First, I'm convinced I'm the only person in the world doing these stupid things and I have a workaround. And second, everyone uses Timidity and won't notice anyway.

The correct fix would be that the note_off of the sounding string gets the same displacement as the new note_on.
Yes. But the code is not remembering what the ON offset was ... quite different that the other tracks (like Chord and Bass) where we set both on and off at the same time ... it's enough just to remember what strings are ON Smiley

Quote
Interesting side note: My MIDI::Guitar module (https://github.com/sciurius/perl-MIDI-Guitar) does it right. Probably by accident  Grin.

Ahh, one point for perl Smiley

I think the key would be a simple documentation fix. I can add some advise in the Rtime section directed to Plectrum tracks.
Logged

My online life: http://www.mellowood.ca
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #7 on: February 15, 2021, 12:46:16 AM »

Thinking a bit more on this I think I can fix the problem using the following logic:  test to see if the point of the new note-on event comes before the beat, search the midi track for a note-off event PAST that time. If found delete it (or would it better to move it to the current point?) and then do the new note-on insert.

I'm thinking that if we're doing a note-on it should not matter if that note is currently sounding or not.

I can try to code this tomorrow. Yes, I know it's a rare situation ... but I really like MMA to cover all bases Smiley
Logged

My online life: http://www.mellowood.ca
sciurius
Sr. Member
****
Posts: 443



« Reply #8 on: February 15, 2021, 07:42:00 AM »

This would eliminate this instance of the problem. But the underlying problem is that for Plectrum tracks, notes are not "start and sound for a specified duration", but "start and sound until stopped". This would require a revision of the algorithms. But the problem is minor, the cases are rare, its users eccentric.

Speaking of "covering all bases": Have you ever realised that notes on stringed instruments are 4-dimensional, while MIDI only deals with 3-dimensional notes? A piano has one "E4", a typical guitar has three of them (E2 string 24th fret, D3 string 14th fret, E4 string open{*}). While these notes have the same pitch, they have a totally different sound. So on a guitar it is quite normal to play multiple notes of the same pitch. On a mandoline all strings are doubled, so all notes sound twice. Since you cannot tune the strings to perfect precision, the two notes are very slightly in discord, causing the characteristic sound of the instrument. Take that, MIDI Smiley.

Also, percussion tracks should not have note_off events. They are ignored by most (all?) players.

{*} This is the same on sax and other blown instruments, where there are usually different fingerings for several basically the same notes.
Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #9 on: February 15, 2021, 04:25:07 PM »

Yeah, that's why I think real musicians playing real instruments still have some future Smiley

One trick I have used in the past for piano, etc. is to have 2 midi tracks duplicating each other but with one track slightly de-tuned. This gives a "wider" sound ... or a muddy one if overdone.

On horns there are so many variables in the way a note is voiced (shape of oral cavity, tongue position, air support, etc) that it is possible to play the same note with the same figuring, using the same mouthpiece and reed, that a good player can make it sound like a different instrument Smiley

Even on piano, the tone of a single note can be changed with different attack and after-touch  techniques. And, then, there is the technique I've seen on videos of the player reaching into the piano and touching various strings while they are sounding.

So much cool stuff to play with ... so little time Smiley
Logged

My online life: http://www.mellowood.ca
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #10 on: February 16, 2021, 12:13:51 AM »

I think the attached patch **may** solve the problem Smiley Mind you, it might strip a whole lot of notes out when it shouldn't. But, I ran a short test file and it seemed to do the right things ... famous last words.

I'm sure you'll let me know!

* patch.txt (2.01 KB - downloaded 155 times.)
Logged

My online life: http://www.mellowood.ca
sciurius
Sr. Member
****
Posts: 443



« Reply #11 on: February 16, 2021, 03:52:56 PM »

I'm not sure the patch is an improvement. Yes, it discards almost all note-off events and apparently software midi's have no problem with that. But the basic problem is still there.

Given the MIDI produced by the test program from post #1, with RTime set to 1.

Code:
        ['note_on', 0, 15, 40, 90],               #       0  001-01-00-00  On:  E1
        ['note_on', 192, 15, 40, 0],              #     192  001-02-00-00  Off: E1
        ['note_on', 1, 15, 40, 90],               #     193  001-02-00-05  On:  E1
        ['note_on', 190, 15, 40, 90],             #     383  001-02-15-55  On:  E1

The first note starts at t=0. The second note starts at t=193 (192 + random delay). However, the first note is stopped at t=192 already.

Also, your patch did not fit the 20.12.1 release, I needed to apply the hunks manually.

Bob, I'm fine with the state of 20.12.1. No need for stopgaps.
Logged
bvdp
Kara-Moon Master
****
Posts: 1436


WWW
« Reply #12 on: February 16, 2021, 04:17:08 PM »

Okay, if you're happy ... I'm happy! I'll forget it.

But, just to let you know ... the patch is designed to stop a prior OFF event from stopping a new ON. So, if you have (mythical offsets):

   0 - on
   40 - off
   41 - on
   80 - off
   79 - on (early due to rnd)
   120 - off

the last ON event will only sound for 1 tick and the OFF at 120 will mute a not-sounding string. Well, that's what I think should happen Smiley Could you check again and see if I'm right Smiley And, if it's needed or not. Somehow I do feel somewhat uncomfortable with the patch.

Oh, the patch was make using 20.12.
Logged

My online life: http://www.mellowood.ca
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.055 seconds with 20 queries.