Rock Band Pro MIDI & Tech Info Discussion

FOF discussion only. Do NOT post help questions here!
This topic is 12 years and 3 months old. Instead of replying, please begin a new topic, or search for another related topic that may be more suitable.
THE HYPNOTOAD!
User avatar
thekiwimaddog
Member
Posts: 485
Joined: December 11th, 2009
Reputation: 0

Re: Rock Band Pro MIDI & Tech Info Discussion

Postby thekiwimaddog » Sun Apr 24, 2011 3:20 am

raynebc wrote:I was comparing chords given in the trainer for medium versus hard and I have found that the game displays the correct name of the chord based on what it has you play. Ie. if you play a barred F#m chord in hard difficulty, the resulting 2 string chord they give you in medium difficulty would have the correct chord name (ie. F#5) given. This means that the MIDI either has the correct name for every chord in every difficulty or the more likely scenario that the game engine determines the correct name by looking it up against a list of chords (ie. note F# and note C# form a F#5 chord). This will probably be the best way for Phase Shift and EOF to go, meaning that the correct tuning will have to be defined for each chart (or assumed to be standard tuning). I can start working on a chord database, but it could be slow going unless I can find a complete list of all chords (I don't care about guitar chords, just standard notes like the F#5 chord example I gave). The alternative is that custom defined chord names will need to be defined on a per difficulty basis.


Thanks for the info and I agree with your conclusion. Just wondering what the few chord names that are listed as text are for.
Overides maybe?
Or could they be Key Changes?

One question, what chord name would be displayed if there is only a single string? Or don't it show chords in that situation?

Thanks
David
Image
Jpop fanatic
raynebc
Moderator
Posts: 5671
Joined: April 20th, 2008
Location: Megumi Island
Reputation: 111

Re: Rock Band Pro MIDI & Tech Info Discussion

Postby raynebc » Sun Apr 24, 2011 3:44 am

I don't think that a name should be listed for non chords, unless it's just the note name (ie. A, B, C, D, E, F, G). A chord name should always have something more specific than that. When people are referring to a C chord, it is actually a C major chord, so "C" could be used to indicate a single note. I'm guessing the text is just an override. As far as key changes, I don't see why they would exist in RB3. RB3 (as far as I'm aware) doesn't even mention anywhere during gameplay if the song changes key, and since the game doesn't display standard music notation (instead instructing the user which specific piano keys and string frets to use to play each and every note), key changes should be irrelevant.

A while back, I allowed for EOF's chart format to store the tuning of each of the six strings. I think if we're going by a note name based chord database (ie. F#5 = F# + C#), storing a value from 0 to 11 (half steps away from some note such as A or C) should be logical. This could be defined as a song.ini tag, such as "tuning = 7 0 5 10 2 7" (half steps above A for each string, standard tuning E A D G B E). Other possible tuning notation styles (ie. half steps above/below standard tuning) seem to me to be less straightforward. That the high and low E are in different octaves shouldn't have an effect on how they join with other notes to form a chord. Once the tuning tag gets ironed out, we could worry about other tags such as for the presence of a capo. Ultimately, it would be great for Phase Shift to allow songs to be sorted by tuning, so when somebody tunes their guitar, they can play multiple songs in a row before having to re-tune for a different song.

If anybody more versed in music theory has any corrections or advice, please chime in here, because I'm pulling this from my limited amount of knowledge on the subject.
THE HYPNOTOAD!
User avatar
thekiwimaddog
Member
Posts: 485
Joined: December 11th, 2009
Reputation: 0

Re: Rock Band Pro MIDI & Tech Info Discussion

Postby thekiwimaddog » Sun Apr 24, 2011 5:07 am

raynebc wrote:I don't think that a name should be listed for non chords, unless it's just the note name (ie. A, B, C, D, E, F, G). A chord name should always have something more specific than that. When people are referring to a C chord, it is actually a C major chord, so "C" could be used to indicate a single note. I'm guessing the text is just an override. As far as key changes, I don't see why they would exist in RB3. RB3 (as far as I'm aware) doesn't even mention anywhere during gameplay if the song changes key, and since the game doesn't display standard music notation (instead instructing the user which specific piano keys and string frets to use to play each and every note), key changes should be irrelevant.

A while back, I allowed for EOF's chart format to store the tuning of each of the six strings. I think if we're going by a note name based chord database (ie. F#5 = F# + C#), storing a value from 0 to 11 (half steps away from some note such as A or C) should be logical. This could be defined as a song.ini tag, such as "tuning = 7 0 5 10 2 7" (half steps above A for each string, standard tuning E A D G B E). Other possible tuning notation styles (ie. half steps above/below standard tuning) seem to me to be less straightforward. That the high and low E are in different octaves shouldn't have an effect on how they join with other notes to form a chord. Once the tuning tag gets ironed out, we could worry about other tags such as for the presence of a capo. Ultimately, it would be great for Phase Shift to allow songs to be sorted by tuning, so when somebody tunes their guitar, they can play multiple songs in a row before having to re-tune for a different song.

If anybody more versed in music theory has any corrections or advice, please chime in here, because I'm pulling this from my limited amount of knowledge on the subject.


I personally would think the tuning should be relative to the standard tuning. The default would then just be 0 0 0 0 0 0 . So drop D would be -2 0 0 0 0 0 . it's quite common in tabs for people to refer to tuning changes like "Tune A Full Step Down" Which would be easy to set as it would just be -2 -2 -2 -2 -2 -2.

In regards to the Low And High E's being in different octaves, I'd think it is important that you know the octave of each note for some chords.
e.g. Take the chord C7. The 7th note is a Bb. However if this was on a lower octave it would be a C/Bb. I know that we could make a rule where the EOF/PS assumes that the high E is an octave higher but I don't know enough about chords to be sure that there isn't a situation where this could be problematic.

But I'm the same as you on this I don't know enough about music theory to be confident what I'm saying is true.

Thanks
David
Image
Jpop fanatic
raynebc
Moderator
Posts: 5671
Joined: April 20th, 2008
Location: Megumi Island
Reputation: 111

Re: Rock Band Pro MIDI & Tech Info Discussion

Postby raynebc » Sun Apr 24, 2011 5:29 am

Making the tuning tag relative to standard makes good sense for 6 string guitar, but it gets more complicated for bass. 4 string bass's standard tuning is EADG whereas 6 string bass uses BEADGC. This complication aside, it shouldn't matter much whether relative or absolute tuning values are used, the charting application can assume standard tuning and have the user tune up/down each string as necessary, like with this web application:
http://www.blackbeltguitar.com/ChordScaleGenerator.php
THE HYPNOTOAD!
User avatar
thekiwimaddog
Member
Posts: 485
Joined: December 11th, 2009
Reputation: 0

Re: Rock Band Pro MIDI & Tech Info Discussion

Postby thekiwimaddog » Sun Apr 24, 2011 5:58 am

I was wondering if you would be happy for us to share a chord database so we can keep them synced.
So we would have a dat file chords.dat and have it layed out like this:
C = X 3 2 0 1 0
Dm = X X 0 2 3 1
E = 0 2 2 1 0 0

etc...

Also this would allow for a seperate chords.dat to be added to each song folder if you want to overide / add extra chords for that song if needed.

Thoughts?

David
Image
Jpop fanatic
raynebc
Moderator
Posts: 5671
Joined: April 20th, 2008
Location: Megumi Island
Reputation: 111

Re: Rock Band Pro MIDI & Tech Info Discussion

Postby raynebc » Sun Apr 24, 2011 4:38 pm

In order to make the chord database equally usable for guitar, bass and piano, it might be easiest to have the database work like the web application I linked to earlier. My reasoning is that even if 5 notes are played for a C major chord on guitar (in the variation you gave, that is C, E, G, C, E) the real chord is just 3 notes (C, E, G). Leaving the extraneous notes out should make it easier to look up the chord for any instrument, requiring only one definition per chord instead of defining each possible variation to play it on guitar, making the database much smaller. The lookup routine could work kind of like this:

Code: Select all

struct _chord_entry
{
   unsigned int number;   //The number of notes in this chord
   unsigned int notes[12];   //An array indicating which notes are present in the chord, where notes[0] refers to A, notes[1] refers to A#, etc.
   char *name;      //A string that contains this chord's name (ie. "Cmaj")
};

struct _chord_database
{
   unsigned int entries;      //The number of chord entries
   struct _chord_entry *chords;   //An array of chord entries
};

struct _chord_database chord_database;   //The database that is populated with chord data

...

char *guitarchordlookup(int *chord, int *tuning, unsigned int strings)
{ //chord is an array of integers, where 0 means the string is played open, -1 means the string is not played, any other number indicates which fret number is being played
  //tuning is an array of integers indicating the absolute tuning of each string (half steps above A), removing the need for the lookup routine to determine the standard tuning
  //for both arrays, the number order is lowest guage string to highest, so tuning[0] refers to the tuning for string 6 (the low E string)
  //strings refers to the number of strings this guitar uses, defining the minimum length of the arrays

   unsigned int ctr, note;
   unsigned int notes_played[12] = {0};   //Will indicate which notes are present in the chord

   //Step 1:  Determine which notes are being played for each string
   for(ctr = 0; ctr < strings; ctr++)
   {
      if(chord[ctr] >= 0)   //If this string is being played
      {
         note = chord[ctr] + tuning[ctr];   //This is the note the string is playing, represented as the number of half steps above A
         notes_played[note % 12] = 1;      //This is the note being played, ie 0 is the same as 12, which is an A note
      }
   }

   //Step 2:  Look for a match in the chord database
   for(ctr = 0; ctr < chord_database.entries; ctr++)
   {
      if(memcmp(chord_database.chords[ctr].notes,&notes_played,sizeof(notes_played)) == 0)
      {   //If this is a match
         return chord_database.chords[ctr].name;
      }
   }

   return NULL;   //No match was found, so return NULL
}


Taking piano chords into account, it doesn't appear to matter which octave the notes are in and a chord can be played with some notes on the left hand and some on the right hand, ultimately making them octaves apart.
THE HYPNOTOAD!
User avatar
thekiwimaddog
Member
Posts: 485
Joined: December 11th, 2009
Reputation: 0

Re: Rock Band Pro MIDI & Tech Info Discussion

Postby thekiwimaddog » Mon Apr 25, 2011 8:46 am

I still see a problem with "/" chords as "C/G" would not be distinguishable from "C" using this method would it?

C - X32010 - XCEGCE
C/G - 332010 - GCEGCE

David
Image
Jpop fanatic
raynebc
Moderator
Posts: 5671
Joined: April 20th, 2008
Location: Megumi Island
Reputation: 111

Re: Rock Band Pro MIDI & Tech Info Discussion

Postby raynebc » Mon Apr 25, 2011 10:55 am

We can add for the bass note tracking with a little bit more code. Now it could look like the following:

Code: Select all

struct _chord_entry
{
   unsigned int number;   //The number of notes in this chord
   unsigned int notes[12];   //An array indicating which notes are present in the chord, where notes[0] refers to A, notes[1] refers to A#, etc.
   unsigned int bassnote;   //This is the bass (lowest pitch) note in the chord, allowing for distinction between a guitar chord and it's "slash" variations
   char *name;      //A string that contains this chord's name (ie. "Cmaj")
};

struct _chord_database
{
   unsigned int entries;      //The number of chord entries
   struct _chord_entry *chords;   //An array of chord entries
};

struct _chord_database chord_database;   //The database that is populated with chord data

...

char *guitarchordlookup(int *chord, int *tuning, unsigned int strings)
{ //chord is an array of integers, where 0 means the string is played open, -1 means the string is not played, any other number indicates which fret number is being played
  //tuning is an array of integers indicating the absolute tuning of each string (half steps above A), removing the need for the lookup routine to determine the standard tuning
  //for both arrays, the number order is lowest guage string to highest, so tuning[0] refers to the tuning for string 6 (the low E string)
  //strings refers to the number of strings this guitar uses, defining the minimum length of the arrays

   unsigned int ctr, note;
   unsigned int notes_played[12] = {0};   //Will indicate which notes are present in the chord
   int *string_notes = malloc(sizeof(int) * strings);   //Allocate an array large enough to hold the fretted note of each string
   int bassnote = -1;

   if(string_notes == NULL)
      return NULL;

   //Step 1:  Determine which notes are being played for each string
   for(ctr = 0; ctr < strings; ctr++)
   {
      string_notes[ctr] = -1;   //Initialize this string's fretted value to "not played"
      if(chord[ctr] >= 0)   //If this string is being played
      {
         note = chord[ctr] + tuning[ctr];   //This is the note the string is playing, represented as the number of half steps above A
         string_notes[ctr] = note;      //Store this value for processing later if necessary
         notes_played[note % 12] = 1;      //This is the note being played, ie 0 is the same as 12, which is an A note
         if(bassnote < 0)
            bassnote = note;      //Store the lowest pitched note as the bass note
      }
   }

   //Step 2:  Look for a match in the chord database
   for(ctr = 0; ctr < chord_database.entries; ctr++)
   {
      if((memcmp(chord_database.chords[ctr].notes,&notes_played,sizeof(notes_played)) == 0) && (bassnote == chord_database.chords[ctr].bassnote))
      {   //If this is a match
         return chord_database.chords[ctr].name;
      }
   }

   return NULL;   //No match was found, so return NULL
}


The piano chord lookup logic can ignore the bass note logic if necessary.
Jpop fanatic
raynebc
Moderator
Posts: 5671
Joined: April 20th, 2008
Location: Megumi Island
Reputation: 111

Re: Rock Band Pro MIDI & Tech Info Discussion

Postby raynebc » Wed Jun 01, 2011 3:59 am

I've been working on this some more today to improve EOF's pro guitar export code, and have more findings:

Note 108 is used to define the left (fretting) hand position, I assume for the animations. The velocity is seemingly supposed to match the velocity of the lowest used fret for the note/chord.

The root notes appear to be the low numbered MIDI notes at each chord. As a refresher, here was the list I'd put together after cross referencing MIDIs with the chords as they were displayed in-game:
Chord E5: Note #4
Chord F or F5: Note #5
Chord G, G5 or G7: Note #7
Chord Ab or Ab5: Note #8
Chord A5: Note #9
Chord Bbsus4, Bb5 or Bb: Note #10
Chord B5: Note #11
Chord C, C5, Cm7 or Cm7b13: Note #12
Chord D5: Note #14
Chord Eb: Note #15

Filling in the gaps, I believe this is how the root notes are marked:
Any derivation of E = 4
Any derivation of F = 5
Any derivation of Gb = 6
Any derivation of G = 7
Any derivation of Ab = 8
Any derivation of A = 9
Any derivation of Bb = 10
Any derivation of B = 11
Any derivation of C = 12
Any derivation of Db = 13
Any derivation of D = 14
Any derivation of Eb = 15

After I finish the tuning definition logic in EOF, I'll get working on the chord database, and EOF will be able to determine and use the correct root notes automatically.

Edit: I previously made a typo. Root note 6 represents chords in the Gb major scale.
THE HYPNOTOAD!
User avatar
thekiwimaddog
Member
Posts: 485
Joined: December 11th, 2009
Reputation: 0

Re: Rock Band Pro MIDI & Tech Info Discussion

Postby thekiwimaddog » Sat Jun 04, 2011 5:02 pm

raynebc wrote:EOF now detects regular chords, but I haven't started slash chord detection yet. Does anybody know how RB3 marks slash chords in the MIDI file?


It seems the Bass note in "Slash" chords are defined an octave higher.


For example if you look at Space Oddity. The first chord is Fm7/E and notes 5 and 16 are being used. 5=F 16=E.

Can you confirm this?

Thanks
David

Edit :It seems that note 16 is also used for Am/G later on in the song. So It must be more involved.
Image
Jpop fanatic
raynebc
Moderator
Posts: 5671
Joined: April 20th, 2008
Location: Megumi Island
Reputation: 111

Re: Rock Band Pro MIDI & Tech Info Discussion

Postby raynebc » Sat Jun 04, 2011 7:07 pm

thekiwimaddog wrote:It seems the Bass note in "Slash" chords are defined an octave higher.

For example if you look at Space Oddity. The first chord is Fm7/E and notes 5 and 16 are being used. 5=F 16=E.
...
Edit :It seems that note 16 is also used for Am/G later on in the song. So It must be more involved.


After scrutinizing the "Space Oddity" chart closely for an hour or two, I think I've found some interesting stuff:

I do see that notes 5 and 16 are marked, but they wouldn't have enough MIDI numbers between 15 (the root note for the Eb scale) and note 24 (lane 1 for Easy difficulty pro guitar). Since 16 was used again in a slash chord that doesn't involve scale E or a bass note of E, I'm guessing note 16 is a marker for slash chords and the game engine is supposed to determine the correct display name. This is consistent with your other example of Am/G, which is marked with numbers 9 (scale of A) and 16.

Other than that, I did notice some of the following in the MIDI:

Code: Select all

Delta file pos=0x23DD9   Deltas=60   Real time=245193.620000ms   Delta time=133440   Adj. real time=245193.620000ms   Event file pos=0x23DDA   Meta Event: Text Event="[chrd3 Bb]"   Length=10
Delta file pos=0x23DE7   Deltas=0   Real time=245193.620000ms   Delta time=133440   Adj. real time=245193.620000ms   Event file pos=0x23DE8   Meta Event: Text Event="[chrd2 Bb]"   Length=10
Delta file pos=0x23DF5   Deltas=0   Real time=245193.620000ms   Delta time=133440   Adj. real time=245193.620000ms   Event file pos=0x23DF6   Meta Event: Text Event="[chrd1 Bb5]"   Length=11


It seems to me that "[chrd1 ...]", "[chrd2 ...]" and "[chrd3 ...]" manually override the game's chord name detection for Medium, Hard and Expert difficulties, respectively. This would make sense because most chords in Medium difficulty are the simpler open chords like G and two note power chords like Bb5, and there are no chords displayed in Easy difficulty. I propose that we use this naming convention for manually named chords. EOF's chord detection shows the chord at that timestamp to be "Bb5" in Medium and "Bbmaj" in Hard and Expert, so I assume Harmonix put that there because their game engine couldn't detect that chord name or something, and this was a quicker fix than correcting their chord detection.

Comparing the MIDI with a Youtube video, there are various chords that display with no names:
The all strings open chord at 1:19
The muted chord at 1:27
The three chords between 3:03 and 3:05
The eleven chords in the solo starting at 3:37
The two 2-note chords at around 4:35
Something that all of these un-named chords have in common is that they are within a note 17 marker, and no named chords are within a note 17 marker. I believe this is sufficient evidence that a root note of 17 means that the game should not try to display a chord name. I'll update EOF to use this instead of a root note for 'A' when the chord name cannot be determined.

Since note 17 seems to be used in this fashion, that also supports the theory that note 16 is a slash chord marker instead of a marker for a root note of scale of 'E'.

I think I've also found out how to decipher the upstrum and downstrum markers. For example, at the Em strumming part at 1:01, the down strums (the white line underneath the fret numbers is thick on the left side and tapers thinner as it goes to the right side) have a (lane 6+4) midi note on channel 15 with a velocity of 114. The up strums (the white line underneath the fret numbers is thick on the right side and tapers thinner as it goes to the left side) have a (lane 6+4) midi note on channel 13 with a velocity of 96. It only looks like Hard (strum direction is note 81) and Expert (strum direction is note 105) are allowed to have chords close enough to be marked as alt strumming.
THE HYPNOTOAD!
User avatar
thekiwimaddog
Member
Posts: 485
Joined: December 11th, 2009
Reputation: 0

Re: Rock Band Pro MIDI & Tech Info Discussion

Postby thekiwimaddog » Sun Jun 05, 2011 2:44 am

This all seems logical, the strum markers I've known about for a while and are listed in the first post. However, the channel numbers are shifted by 1 as PS starts with CH1 instead of CH0.

David
Image
Jpop fanatic
raynebc
Moderator
Posts: 5671
Joined: April 20th, 2008
Location: Megumi Island
Reputation: 111

Re: Rock Band Pro MIDI & Tech Info Discussion

Postby raynebc » Sun Jun 19, 2011 1:44 pm

Thinking about this some more, I believe all RB3 does for slash chords is: If it sees the slash chord root note marker of 16, it looks up the lowest note played and considers that the bass note. This is consistent with how the Space Oddity's slash chords are displayed: FM7/E, Am/G, E7/G#. It doesn't do a full blown lookup and determine on its own if the chord is a slash chord, the chart's author is expected to specify that. I think in almost all normal cases, the note played on the lowest used string ends up being the bass note, or otherwise the guitarist would have had to tune a string up several half steps so that it plays at or higher than the thinner string adjacent to it, played a fret on a string that is 5 or 6 frets higher than the adjacent thinner string or a mixture of the two. With this in mind, it should simplify how we can have EOF and Phase Shift detect slash chords:

EOF will detect a chord as a slash chord if the lowest played note is not one of the chord's normal notes, but the rest of the chord's notes still contain those necessary for the chord: ie. C/F# would play F# on the low E string, and the usual C, E and G notes. It's not universally agreed in the whole of music theory that a different variation of a chord makes it a slash chord, ie. the first chord in Space Oddity is still an FM7 chord, it's just that they used the low E string to play a note that's already in the chord instead of not use it at all. There's no good way to detect this as a slash chord without an exhaustive pre-built database of each common chord variation and its bass note, so I'll probably have an option in EOF to indicate that the game playing the chart should treat a chord as a slash chord. It would make sense that Harmonix came to this conclusion and is why they chose to mark them the way they did.

Return to “General FOF Discussion”

Who is online

Users browsing this forum: Bing [Bot] and 37 guests