Benutzer-Werkzeuge

Webseiten-Werkzeuge


tools:intervalltrainer-uebung

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige ÜberarbeitungVorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
tools:intervalltrainer-uebung [10/05/2025 18:38] – gelöscht - Externe Bearbeitung (Unknown date) 127.0.0.1tools:intervalltrainer-uebung [10/05/2025 18:39] (aktuell) Eric Weber
Zeile 1: Zeile 1:
 +====== Intervalltrainer | Übungsmodus ======
 +
 +
 +<html>
 +<head>
 +  <meta charset="UTF-8">
 +  <title>Intervalltrainer | Übungsmodus</title>
 +  <style>
 +    body {
 +      font-family: Arial, sans-serif;
 +      margin: 20px;
 +    }
 +    .hidden {
 +      display: none;
 +    }
 +    button {
 +      margin: 5px;
 +      padding: 10px;
 +    }
 +    .correct {
 +      background-color: #8f8;
 +    }
 +    .incorrect {
 +      background-color: #f88;
 +    }
 +    .progress {
 +      margin-top: 10px;
 +      height: 20px;
 +      background: #ddd;
 +      position: relative;
 +    }
 +    .progress-bar {
 +      height: 100%;
 +      background: #4caf50;
 +      width: 0%;
 +    }
 +  </style>
 +</head>
 +<body>
 +
 +  <div>
 +    <label>Abspielart:
 +      <select id="directionSelect">
 +        <option value="up">aufsteigend</option>
 +        <option value="down">absteigend</option>
 +        <option value="harmonic">simultan</option>
 +      </select> <br>
 +    </label>
 +    <label>Schwierigkeitsgrad:
 +      <select id="difficultySelect">
 +        <option value="easy">einfach (alle Intervalle starten ab c1/c2)</option>
 +        <option value="medium">fortgeschritten (alle Intervalle starten von beliebigen Cs)</option>
 +        <option value="hard">Profi (alle Intervalle starten von beliebigen Noten)</option>
 +      </select>
 +    </label>
 +  </div>
 +
 +  <div id="practiceControls">
 +    <div id="intervalButtons"></div>
 +  </div>
 +
 +  <script>
 +    const intervals = [
 +      'Prime', 'kleine Sekunde', 'große Sekunde', 'kleine Terz', 'große Terz',
 +      'Quarte', 'Tritonus', 'Quinte', 'kleine Sexte', 'große Sexte',
 +      'kleine Septime', 'große Septime', 'Oktave'
 +    ];
 +
 +    const semitoneMap = {
 +      'Prime': 0,
 +      'kleine Sekunde': 1,
 +      'große Sekunde': 2,
 +      'kleine Terz': 3,
 +      'große Terz': 4,
 +      'Quarte': 5,
 +      'Tritonus': 6,
 +      'Quinte': 7,
 +      'kleine Sexte': 8,
 +      'große Sexte': 9,
 +      'kleine Septime': 10,
 +      'große Septime': 11,
 +      'Oktave': 12
 +    };
 +
 +    const noteFreqs = {
 +      'C3': 130.81, 'C#3': 138.59, 'D3': 146.83, 'D#3': 155.56, 'E3': 164.81,
 +      'F3': 174.61, 'F#3': 185.00, 'G3': 196.00, 'G#3': 207.65, 'A3': 220.00,
 +      'Bb3': 233.08, 'B3': 246.94, 'C4': 261.63, 'C#4': 277.18, 'D4': 293.66,
 +      'D#4': 311.13, 'E4': 329.63, 'F4': 349.23, 'F#4': 369.99, 'G4': 392.00,
 +      'G#4': 415.30, 'A4': 440.00, 'Bb4': 466.16, 'B4': 493.88, 'C5': 523.25,
 +      'C#5': 554.37, 'D5': 587.33, 'D#5': 622.25, 'E5': 659.26, 'F5': 698.46,
 +      'F#5': 739.99, 'G5': 783.99, 'G#5': 830.61, 'A5': 880.00, 'Bb5': 932.33,
 +      'B5': 987.77, 'C6': 1046.50
 +    };
 +
 +    const practiceControls = document.getElementById("practiceControls");
 +    const intervalButtons = document.getElementById("intervalButtons");
 +
 +    function createPracticeButtons() {
 +      intervalButtons.innerHTML = '';
 +      intervals.forEach(interval => {
 +        const btn = document.createElement("button");
 +        btn.textContent = interval;
 +        btn.onclick = () => playInterval(interval);
 +        intervalButtons.appendChild(btn);
 +      });
 +    }
 +
 +    function getRandomNote(difficulty, direction) {
 +      let pool = [];
 +      if (difficulty === 'easy') {
 +        pool = [direction === 'down' ? 'C5' : 'C4'];
 +      } else if (difficulty === 'medium') {
 +        pool = direction === 'down' ? ['C4', 'C5', 'C6'] : ['C3', 'C4', 'C5'];
 +      } else {
 +        pool = Object.keys(noteFreqs);
 +      }
 +      return pool[Math.floor(Math.random() * pool.length)];
 +    }
 +
 +    function getFrequency(note) {
 +      return noteFreqs[note] || 440;
 +    }
 +
 +    function playTone(frequency, duration = 0.8) {
 +      const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
 +      const oscillator = audioCtx.createOscillator();
 +      const gainNode = audioCtx.createGain();
 +
 +      oscillator.type = 'sine';
 +      oscillator.frequency.setValueAtTime(frequency, audioCtx.currentTime);
 +      oscillator.connect(gainNode);
 +      gainNode.connect(audioCtx.destination);
 +
 +      oscillator.start();
 +      gainNode.gain.exponentialRampToValueAtTime(0.0001, audioCtx.currentTime + duration);
 +      oscillator.stop(audioCtx.currentTime + duration);
 +    }
 +
 +    function playInterval(intervalName, startNote = null) {
 +      const direction = document.getElementById("directionSelect").value;
 +      const difficulty = document.getElementById("difficultySelect").value;
 +      const semitones = semitoneMap[intervalName];
 +
 +      let baseNote = startNote || getRandomNote(difficulty, direction);
 +      let baseFreq = getFrequency(baseNote);
 +      let secondFreq = direction === 'down'
 +        ? baseFreq / Math.pow(2, semitones / 12)
 +        : baseFreq * Math.pow(2, semitones / 12);
 +
 +      if (direction === 'harmonic') {
 +        playTone(baseFreq);
 +        playTone(secondFreq);
 +      } else {
 +        playTone(baseFreq);
 +        setTimeout(() => playTone(secondFreq), 1000);
 +      }
 +    }
 +
 +    createPracticeButtons();
 +  </script>
 +</body>
 +</html>