I don't like using redundant spaces between tokens (but newlines and tab indentations are OK), it's better to be more concise and use ES6 tricks whenever possible.

m7/m9/m11 chords aren't handled correctly (it plays major chords instead):
```js
var PI=Math.PI,TAU=PI*2,
    noteNumbers={
  "C":0,
  "C#":1,"Db":1,
  "D":2,
  "D#":3,"Eb":3,
  "E":4,
  "F":5,
  "F#":6,"Gb":6,
  "G":7,
  "G#":8,"Ab":8,
  "A":9,
  "A#":10,"Bb":10,
  "B":11
};
//parse a chord string into root note, modifiers, and bass note
function parseChordString(chordStr){
  /*
  //split the chord by slash to separate chord and bass note
  var parts=chordStr.split('/'),
      chordPart=parts[0],
      bassNote=parts[1]||null;
  */
  //check if the chord contains a bass note
  var bassNoteMatch=chordStr.match(/\/([A-G][#b]?)$/),
      bassNote=null;
  if(bassNoteMatch){
    bassNote=bassNoteMatch[1];
    chordStr=chordStr.slice(0,chordStr.length-bassNoteMatch[0].length); //remove bass note part from chordStr
  }
  //extract the root note and modifiers from the chordStr
  var match=chordStr.match(/^([A-G][#b]?)(.*)$/);
  if(!match)throw new Error("Invalid chord: "+chordStr);
  var rootNote=match[1],
      modifiers=match[2];
  return{
    rootNote:rootNote,
    modifiers:modifiers,
    bassNote:bassNote
  };
}
//function to parse chord modifiers into tokens
function parseModifiers(modifiers){
  // Patterns for different tokens
  var patterns=[
    {pattern:/^maj7/,token:'maj7'},
    {pattern:/^maj9/,token:'maj9'},
    {pattern:/^maj11/,token:'maj11'},
    {pattern:/^maj13/,token:'maj13'},
    {pattern:/^maj/,token:'maj'},
    {pattern:/^m(in)?\/?maj7/,token:'minmaj7'},
    {pattern:/^m(in)?13/,token:'min13'},
    {pattern:/^m(in)?11/,token:'min11'},
    {pattern:/^m(in)?9/,token:'min9'},
    {pattern:/^m(in)?7/,token:'min7'},
    {pattern:/^m(in)?/,token:'min'},
    {pattern:/^dim7/,token:'dim7'},
    {pattern:/^dim/,token:'dim'},
    {pattern:/^aug/,token:'aug'},
    {pattern:/^sus2/,token:'sus2'},
    {pattern:/^sus4/,token:'sus4'},
    {pattern:/^sus/,token:'sus'},
    {pattern:/^add(#|b)?\d+/,token:'add'},
    {pattern:/^(\d+)(add)?(#|b)?\d*/,token:'extension'},
    {pattern:/^6\/?9/,token:'6/9'},
    {pattern:/^7#9/,token:'7#9'},
    {pattern:/^7b9/,token:'7b9'},
    {pattern:/^7#5b9/,token:'7#5b9'},
    {pattern:/^7#5/,token:'7#5'},
    {pattern:/^7b5/,token:'7b5'},
    {pattern:/^7/,token:'7'},
    {pattern:/^5/,token:'5'},
    {pattern:/^6/,token:'6'},
    {pattern:/^9/,token:'9'},
    {pattern:/^11/,token:'11'},
    {pattern:/^13/,token:'13'},
    {pattern:/^#\d+/,token:'sharp'},
    {pattern:/^b\d+/,token:'flat'},
    {pattern:/^#/,token:'#'},
    {pattern:/^b/,token:'b'},
    {pattern:/^\//,token:'/'}
  ];
  var tokens=[],
      str=modifiers;
  while(str.length>0){
    var matched=false;
    for(var i=0;i<patterns.length;i++){
      var res=patterns[i].pattern.exec(str);
      if(res){
        if(patterns[i].token=='number'||patterns[i].token=='add'||patterns[i].token=='sharp'||patterns[i].token=='flat') {
          tokens.push(res[0]);
        }else{
          tokens.push(patterns[i].token);
        }
        str=str.substr(res[0].length);
        matched=true;
        break;
      }
    }
    if(!matched){
      //unrecognized token, skip one character
      str=str.substr(1);
    }
  }
  return tokens;
}
//helper function to get interval from scale degree
var intervalsMap={1:0,2:2,3:4,4:5,5:7,6:9,7:11,9:14,11:17,13:21};
function getIntervalFromDegree(degree){return intervalsMap[degree]||0;}
//function to get chord intervals based on modifiers
function getChordIntervals(modifiers){
  var tokens=parseModifiers(modifiers),
      intervals=[];
  //start with basic triad
  var chordQuality='major'; //default
  if(tokens.includes('maj')){
    chordQuality='major';
  }else if(tokens.includes('min')||tokens.includes('m')){
    chordQuality='minor';
  }else if(tokens.includes('dim')){
    chordQuality='diminished';
  }else if(tokens.includes('aug')){
    chordQuality='augmented';
  }
  //build the basic triad intervals
  if(tokens.includes('minmaj7')){
    chordQuality='minor';
    intervals.push(0,3,7,11); //minor triad with major 7th
  }else{
    if(chordQuality=='major'){
      intervals.push(0,4,7);
    }else if(chordQuality=='minor'){
      intervals.push(0,3,7);
    }else if(chordQuality=='diminished'){
      intervals.push(0,3,6);
    }else if(chordQuality=='augmented'){
      intervals.push(0,4,8);
    }
    //handle extensions and added tones
    if(tokens.includes('maj7')){
      intervals.push(11);
    }else if(tokens.includes('7')){
      intervals.push(10);
    }
  }
  if(tokens.includes('9')){
    if(!intervals.includes(10)&&!intervals.includes(11))
      intervals.push(10); //add dominant 7th
    intervals.push(14);
  }
  if(tokens.includes('11')){
    if(!intervals.includes(10)&&!intervals.includes(11))
      intervals.push(10);
    if(!intervals.includes(14))intervals.push(14);
    intervals.push(17);
  }
  if(tokens.includes('13')){
    if(!intervals.includes(10)&&!intervals.includes(11))
      intervals.push(10);
    if(!intervals.includes(14))intervals.push(14);
    if(!intervals.includes(17))intervals.push(17);
    intervals.push(21);
  }
  if(tokens.includes('6/9'))
    intervals.push(9,14);
  if(tokens.includes('6'))
    intervals.push(9);
  if(tokens.includes('add')){
    tokens.filter(t=>t.startsWith('add')).forEach(t=>{
      var number=parseInt(t.replace('add','').replace('#','').replace('b','')),
          interval = getIntervalFromDegree(number);
      if(t.includes('#'))interval++;
      if(t.includes('b'))interval--;
      intervals.push(interval);
    });
  }
  if(tokens.includes('extension')){
    tokens.filter(t=>t.match(/^\d+/)).forEach(t=>{
      var number=parseInt(t),
          interval=getIntervalFromDegree(number);
      intervals.push(interval);
      //handle alterations like 9b13
      if(t.includes('b')){
        interval=getIntervalFromDegree(parseInt(t.match(/\d+/g)[1]))-1;
        intervals.push(interval);
      }else if(t.includes('#')){
        interval=getIntervalFromDegree(parseInt(t.match(/\d+/g)[1]))+1;
        intervals.push(interval);
      }
    });
  }
  if(tokens.includes('sus2')){
    //replace the third with major 2nd
    var index=intervals.indexOf(chordQuality=='major'?4:3);
    if(index>=0)intervals[index]=2;
  }else if(tokens.includes('sus4')){
    //replace the third with perfect 4th
    var index=intervals.indexOf(chordQuality=='major'?4:3);
    if(index>=0)intervals[index]=5;
  }
  //handle alterations
  for(var i=0;i<tokens.length;i++){
    if(tokens[i]=='#5'){
      //replace the fifth with augmented fifth
      var index=intervals.indexOf(7);
      if(index>=0)intervals[index]=8;
    }else if(tokens[i]=='b5'){
      //replace the fifth with diminished fifth
      var index=intervals.indexOf(7);
      if(index>=0)intervals[index]=6;
    }else if(tokens[i]=='#9'){
      intervals.push(15); //sharp ninth
    }else if(tokens[i]=='b9'){
      intervals.push(13); //flat ninth
    }else if(tokens[i]=='#11'){
      intervals.push(18); //sharp eleventh
    }else if(tokens[i]=='b13'){
      intervals.push(20); //flat thirteenth
    }
  }
  //remove duplicates and sort intervals
  intervals=intervals.filter((v,i,a)=>a.indexOf(v)===i);
  intervals.sort((a,b)=>a-b);
  return intervals;
}
function note(n,base=440,keys=12){return base*Math.pow(2,n/keys);}
function sine(x){return Math.sin(TAU*x);}
function pulse(x){return x%1<.5?-1:1;};
//limit frequency within a given range
function limitFrequency(freq,minFreq,maxFreq){
  while(freq<minFreq)freq*=2;
  while(freq>maxFreq)freq/=2;
  return freq;
}
var chordDuration=2, //seconds per chord
    //chords="Amaj7sus2/Ab Gmaj7sus2 C69#11 Bm11 Ab7#5b9 Dbm11 Cmaj7b5/6 Abm11 F#m11".split(" "),
    chords="Gb7 Gmmaj7 Emmaj9 Ab9addb13/C Gbaug Bmaj9 Abm11 Dbm11 Gb7/#11 Dbmaj9sus2 Eb13sus4 Dbm9".split(" "),
    totalChords = chords.length;
return function dsp(t) {
  var out=0,
      chordIndex=Math.floor(t/chordDuration)%totalChords,
      chordTime=t%chordDuration,
      chordStr=chords[chordIndex],
      chord=parseChordString(chordStr),
      rootNote=chord.rootNote,
      modifiers=chord.modifiers,
      bassNote=chord.bassNote||chord.rootNote,
      intervals=getChordIntervals(modifiers),
      rootNoteNumber=noteNumbers[rootNote],
      //get the semitone offset from A4 (note number 9)
      semitoneOffset=rootNoteNumber-9,
      //calculate frequencies and sum the sine waves
      numNotes=intervals.length+1; //number of notes in the chord including bass
  for(var i=0;i<intervals.length;i++){
    var n=semitoneOffset+intervals[i], //total semitone offset from A4
        freq=limitFrequency(note(n),220,880);
    out+=sine(freq*t);
  }
  //add the bass note an octave lower
  if(bassNote){
    var bassNoteNumber=noteNumbers[bassNote],
        bassSemitoneOffset=bassNoteNumber-9-12; //bass an octave lower
        bassFreq=note(bassSemitoneOffset);
    out+=sine(bassFreq*t);
  }
  //normalize output
  out=out/numNotes;
  return out;
}
```