Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm trying to do some evaluation on notes (specifically the pitches) imported from a MIDI file. I've imported a list containing tracks of sound notes with Import["path/to/midi.mid", "SoundNotes"] and a track's sound notes look like the following:

{ SoundNote["G4", {0., 0.5}, "Piano", SoundVolume -> 0.501961], 
  SoundNote["C5", {0.5, 1.}, "Piano", SoundVolume -> 0.501961], 
  SoundNote["D5", {1., 1.5}, "Piano", SoundVolume -> 0.501961],
  ...
}

I'm attempting to get the pitch out of each SoundNote, treating each SoundNote as a list and grabbing the first value with aNote[[1]]. However, this returns a note string such as "C5". Is there a way to get a numeric representation of the pitch, in either MIDI scale (Middle C = 60) or Mathematica's scale (Middle C = 0)? I haven't seen any way to pull information from a SoundNote in the docs, unless I'm missing something.

share|improve this question
1  
Good question. If my memory serves me right, last time I did this I just created a replacement table "C4" -> 0, etc. and used that. There might be something better though. –  Szabolcs Feb 26 at 0:37

1 Answer 1

up vote 3 down vote accepted

If someone has a native solution I'll mark it as the correct answer, but I ended up making a quick function to convert the string into a numeric pitch. I go off the assumption that the MIDI import only uses sharps and no flats as representation for SoundNote pitch.

(* Converts note string into pitch relative to middle C = 0 *)
stringToPitch[string_String] := 
 Module[{noteValues, noteList, pitch},
   noteValues = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
   noteList = StringCases[string, {RegularExpression["[A-G]#?"], RegularExpression["\\d+"]}];
   pitch = Position[noteValues, First[noteList]][[1, 1]] - 1;
   ((ToExpression[noteList[[2]]] - 4)*12) + pitch
 ]

Note that this is relative to middle C like Mathematica tones (where C4 = MiddleC = 0). The function can be called as

stringToPitch["C#4"]

(* ==> 1 *)
share|improve this answer
    
+1 for providing a ready to use function. I cleaned it up a bit, I hope you don't mind. It is recommended not to use Return when it's not actually necessary and pitch was not localized. –  Szabolcs Feb 26 at 2:48
    
Still getting used to the language, thanks for cleaning it up! –  pk-nb Feb 26 at 2:49
    
Noticed the + pitch was accidentally removed, added it back to make sure the function is still correct. Feel free to further edit if necessary. –  pk-nb Feb 26 at 2:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.