Sound Modification

I define a function uniqueSounds, which is an integer equal to the number of non-empty, unique sound channels [instruments] in midiSoundNotes. The second output shows the length of each sublist of midiSoundNotes; the number of notes for each instrument.

notes contains a list of strings representing the initial tone in the form of {note|octave}; Range[uniqueSounds]+1 allows modification on any channel except the empty padding

notes[[n]] contains the n^th sound channel of midiSoundNotes

noteShift[n_] provides the n^th channel's note section with octave removed; acquired by dropping the last character.

fullToneShift[oct_, note_, channel_] shifts each note of channel [max uniqueSounds] by \[PlusMinus]oct octaves and \[PlusMinus]note notes. Initially, I ignored the case of shifting upward from G# to A and shifting downward from A to G#--that is to say, I left the octave untouched in those cases. The result was musically confusing, as any note that shifted over the boundary was sent 12 half-steps lower or higher than intended. It proved a formidable challenge to change the octave in addition to the note when performing such a shift.

FTS, a second function contained within fullToneShift, creates a list containing each {note+octave} in its own sublist.
ReplaceRepeated[ ] modifies noteShift[ch] (from above) by stepping each note up or down (If[n>0...]) "note" times (MaxIterations->Abs[n])
ToExpression[ ]+o isolates the octave section, converts to integer, and adds "oct" to the octave value
Riffle[ ] threads these two components together to create a single list
Partition[ , 2] groups this list into sublists containing {note+octave}
Total /@ sums the values, which takes any possible octave shifts into account when noteShift[ch] occurs
Partition[ , 1] returns this list to sublists containing {octave + "note"}
This data is in a meaningless { Plus[ _Integer , _String ] } format.

fullToneShift structures and formats the list generated in FTS, containing each modified note in executable form
Riffle[ ] threads the note segment FTS[ ][[All, 1, 2]] and octave segment FTS[ ][[All, 1, 1]] together in a single list.
ToString /@ converts each component of the riffled list into the correct format for midiSoundNotes
Partition[ , 2] groups the properly-formatted {Note, Octave} into sublists
StringJoin/@ joins and flattens each sublist

q[x[n]_, y[n]_, ch[n]_] maps fullToneShift back to midiSoundNotes; channel input is not required--channel will default to 1, 2, ..., n as needed
ReplacePart[ ] replaces some component of midiSoundNotes with other data
{{ch[n]+1, n_, 1} -> fullToneShift[x, y, ch][[n]]} identifies the data to be changed in midiSoundNotes and the data to replace it with
Flatten[ ] is necessary to remove padding for Sound[ ] to function properly
Sound[q[x, y]] will play the shifted data, sending {x,y,ch} to fullToneShift[x, y, ch] and then to FTS[x, y, ch]

Finally, 5 examples:
	[1] Octave shift on all channels [ Octave = { +1, +1, -1, -1 }; Note = { 0, 0, 0, 0 } ]
	[2] Note shift on all channels [ Note = { -1, -2, +1, +2 }; Octave = { 0, 0, 0, 0 } ]
	[3] Octave+Note shift on 1 channel [ Channel = 3 | "New Age" | Note = Octave = { +1 } ]
	[4] Pseudo-random Octave+Note shift on all channels
	[5] Original midi sound