summaryrefslogtreecommitdiff
path: root/stories/music/transpose.rst
blob: 4b34b429e8c2e09f631e2b4a2feba87afe0acf33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
.. link:
.. description:
.. tags:
.. date: 1998/08/03 19:10:08
.. title: Live no-barré transposer tool
.. slug: ../music/transpose

.. raw:: html

  <script>
  function addRow() {
    var row = document.getElementById("chord-row-0");
    var addbutton = document.getElementById("addButton");
    var ourdiv = document.getElementById("transposer");
    var cloned = row.cloneNode(true);
    var newid = window.rowid || 1;
    window.rowid = newid + 1;
    cloned.setAttribute( "id", "chord-row-" + newid );
    ourdiv.insertBefore(cloned, addbutton);
  }
  function isbarre(nv) {
    var nobarre = [0,2,5,24,25,26,27,28,29,48,49,50,51,52,53,65,84,86,88,108,109,110,111,112,113,132,134];
    for( var len = nobarre.length, i=0; i<len; ++i )
      if( nobarre[i] == nv )
        return 0;
    return 1;
  }
  function note_to_name(nv) {
    return ["C","C#","D","D#","E","F","F#","G","G#","A","B","H"][~~(nv/12)]+["","m","7","m7","maj6","maj7"][nv%12];
  }
  function updateTrans() {
    var resulttext = document.getElementById("result");
    var notelist = document.getElementsByClassName("chord-row");
    var impossible_offsets = 0;
    var notes = [];

    for (var len = notelist.length, i=0; i<len; ++i) {
      var note = notelist[i].getElementsByClassName("note");
      var modifier = notelist[i].getElementsByClassName("modifier");
      var nv = 1 * note[0].value;
      var mv = 1 * modifier[0].value;
      if( nv >= 0 ) {
        notes.push( ( nv * 12 ) + mv );
        // test all transpositions for suitable chords
        for (var off = 0; off < 12; ++off ) {
          if ( isbarre( mv + 12 * ( ( nv + off ) % 12 ) ) )
            impossible_offsets |= 1<<off;
        }
      }
    }
    if( impossible_offsets == 0xfff ) {
      resulttext.innerHTML = 'Keine Transposition / Not possible';
    } else {
      var outtext = '';
      for( var off = 0; off < 12; ++off ) {
        if( !( impossible_offsets & (1<<off) ) ) {
          outtext += '<table><tr><th>original</th><th>transpose</th></tr>';
          for( var len = notes.length, i=0; i<len; ++i ) {
            var transposed = 12 * ( ( ~~( notes[i] / 12 ) + off ) % 12 ) + ( notes[i] % 12 );
            if( ( ( notes %12 ) != 2 ) && transposed == 132 )
                outtext += "<tr><td>" + note_to_name(notes[i]) + "</td><td>H7 (unclean)</td></td>";
            else
                outtext += "<tr><td>" + note_to_name(notes[i]) + "</td><td>" + note_to_name(transposed) + "</td></tr>";
          }
        }
      }
      resulttext.innerHTML = outtext + "</table>";
    }
  }

  </script>
  <style>
    table {
      border: 1px black solid;
      border-collapse: none;
      margin: 2em 2em 0em 0em;
      float: left;
    }
    td, th {
      padding: 8px;
      border: 1px silver dotted;
    }
    .chord-row, .addButton {
      margin-bottom: 1em;
    }
  </style>
  <div id="transposer">
  <div class="chord-row" id="chord-row-0">
  <select class="note" onchange="updateTrans()">
    <option value="-1">Note</option>
    <option value="0">C</option>
    <option value="1">C# / Db</option>
    <option value="2">D</option>
    <option value="3">D# / Eb</option>
    <option value="4">E</option>
    <option value="5">F</option>
    <option value="6">F# / Gb</option>
    <option value="7">G</option>
    <option value="8">G# / Ab</option>
    <option value="9">A</option>
    <option value="10">A# / B</option>
    <option value="10">H</option>
  </select>
  <select class="modifier" onchange="updateTrans()">
    <option value="0">Dur / major</option>
    <option value="1">Moll / minor</option>
    <option value="2">7</option>
    <option value="3">Moll7 / min7</option>
    <option value="4">Maj6</option>
    <option value="5">Maj7</option>
  </select>
  </div>
  <button id="addButton" type="button" onclick="addRow()">+</button>
  <div id="result"></div>
  </div>