Benutzer-Werkzeuge

Webseiten-Werkzeuge


tools:intervalltrainer2

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige ÜberarbeitungVorherige Überarbeitung
tools:intervalltrainer2 [10/05/2025 18:33] – ↷ Seitename wurde von tools:intervalltrainer2 auf tools:intervalltrainer-pruefung geändert Eric Webertools:intervalltrainer2 [21/09/2025 16:11] (aktuell) – angelegt Eric Weber
Zeile 1: Zeile 1:
 +<html>
 +<html lang="de">
 +<head>
 +    <meta charset="UTF-8">
 +    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 +    <title>Intervalltrainer 2</title>
 +    <style>
 +        /* Reset nur für die Anwendung - keine globalen Styles */
 +        .interval-training-app * {
 +            margin: 0;
 +            padding: 0;
 +            box-sizing: border-box;
 +        }
  
 +        .interval-training-app {
 +            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 +            color: #2d3748;
 +            max-width: 900px;
 +            margin: 0 auto;
 +            padding: 20px;
 +            /* Kein Hintergrund - transparent */
 +        }
 +
 +        .interval-training-app h1 {
 +            text-align: center;
 +            color: #2d3748;
 +            margin-bottom: 30px;
 +            font-size: 2.5em;
 +            text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);
 +            font-weight: 700;
 +        }
 +
 +        .interval-training-app .card {
 +            background: rgba(255, 255, 255, 0.95);
 +            backdrop-filter: blur(10px);
 +            border-radius: 15px;
 +            padding: 25px;
 +            margin-bottom: 20px;
 +            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
 +            border: 2px solid rgba(45, 55, 72, 0.1);
 +        }
 +
 +        .interval-training-app h2 {
 +            color: #2d3748;
 +            margin-bottom: 15px;
 +            border-bottom: 2px solid #e2e8f0;
 +            padding-bottom: 10px;
 +            font-size: 1.4em;
 +            font-weight: 600;
 +        }
 +
 +        .interval-training-app .section {
 +            margin-bottom: 25px;
 +        }
 +
 +        .interval-training-app .checkbox-grid {
 +            display: grid;
 +            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
 +            gap: 10px;
 +            margin-bottom: 15px;
 +        }
 +
 +        .interval-training-app .checkbox-item {
 +            display: flex;
 +            align-items: center;
 +            padding: 10px 12px;
 +            background: rgba(247, 250, 252, 0.9);
 +            border-radius: 8px;
 +            border: 1px solid #cbd5e0;
 +            transition: all 0.2s;
 +            cursor: pointer;
 +        }
 +
 +        .interval-training-app .checkbox-item:hover {
 +            background: rgba(237, 242, 247, 0.9);
 +            transform: translateY(-1px);
 +            border-color: #a0aec0;
 +        }
 +
 +        .interval-training-app .checkbox-item input[type="checkbox"] {
 +            margin-right: 10px;
 +            transform: scale(1.2);
 +            cursor: pointer;
 +        }
 +
 +        .interval-training-app .checkbox-item label {
 +            cursor: pointer;
 +            font-weight: 500;
 +        }
 +
 +        .interval-training-app .control-buttons {
 +            display: flex;
 +            gap: 10px;
 +            margin-bottom: 20px;
 +            flex-wrap: wrap;
 +        }
 +
 +        .interval-training-app .btn {
 +            padding: 12px 24px;
 +            border: none;
 +            border-radius: 8px;
 +            cursor: pointer;
 +            font-size: 16px;
 +            font-weight: 600;
 +            transition: all 0.3s;
 +            text-transform: uppercase;
 +            letter-spacing: 0.5px;
 +            font-family: inherit;
 +        }
 +
 +        .interval-training-app .btn-primary {
 +            background: linear-gradient(135deg, #4299e1 0%, #3182ce 100%);
 +            color: white;
 +            border: 2px solid transparent;
 +        }
 +
 +        .interval-training-app .btn-secondary {
 +            background: #718096;
 +            color: white;
 +            border: 2px solid transparent;
 +        }
 +
 +        .interval-training-app .btn-success {
 +            background: #48bb78;
 +            color: white;
 +            border: 2px solid transparent;
 +        }
 +
 +        .interval-training-app .btn-danger {
 +            background: #f56565;
 +            color: white;
 +            border: 2px solid transparent;
 +        }
 +
 +        .interval-training-app .btn:hover {
 +            transform: translateY(-2px);
 +            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
 +        }
 +
 +        .interval-training-app .btn:disabled {
 +            opacity: 0.6;
 +            cursor: not-allowed;
 +            transform: none;
 +        }
 +
 +        .interval-training-app .radio-group {
 +            display: flex;
 +            flex-direction: column;
 +            gap: 10px;
 +        }
 +
 +        .interval-training-app .radio-item {
 +            display: flex;
 +            align-items: center;
 +            padding: 12px 15px;
 +            background: rgba(247, 250, 252, 0.9);
 +            border-radius: 8px;
 +            border: 1px solid #cbd5e0;
 +            cursor: pointer;
 +            transition: all 0.2s;
 +        }
 +
 +        .interval-training-app .radio-item:hover {
 +            background: rgba(237, 242, 247, 0.9);
 +            border-color: #a0aec0;
 +        }
 +
 +        .interval-training-app .radio-item input[type="radio"] {
 +            margin-right: 12px;
 +            transform: scale(1.2);
 +            cursor: pointer;
 +        }
 +
 +        .interval-training-app .radio-item label {
 +            cursor: pointer;
 +            font-weight: 500;
 +        }
 +
 +        .interval-training-app .quiz-container {
 +            display: none;
 +        }
 +
 +        .interval-training-app .question-info {
 +            text-align: center;
 +            margin-bottom: 20px;
 +            font-size: 18px;
 +            color: #4a5568;
 +            font-weight: 600;
 +        }
 +
 +        .interval-training-app .audio-controls {
 +            text-align: center;
 +            margin: 20px 0;
 +        }
 +
 +        .interval-training-app .play-btn {
 +            background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
 +            color: white;
 +            border: none;
 +            border-radius: 50%;
 +            width: 80px;
 +            height: 80px;
 +            font-size: 24px;
 +            cursor: pointer;
 +            transition: all 0.3s;
 +            box-shadow: 0 4px 15px rgba(72, 187, 120, 0.4);
 +        }
 +
 +        .interval-training-app .play-btn:hover {
 +            transform: scale(1.1);
 +            box-shadow: 0 6px 20px rgba(72, 187, 120, 0.6);
 +        }
 +
 +        .interval-training-app .answer-options {
 +            display: grid;
 +            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
 +            gap: 10px;
 +            margin: 20px 0;
 +        }
 +
 +        .interval-training-app .answer-btn {
 +            padding: 15px 20px;
 +            border: 2px solid #cbd5e0;
 +            background: rgba(255, 255, 255, 0.9);
 +            border-radius: 8px;
 +            cursor: pointer;
 +            font-size: 16px;
 +            font-weight: 500;
 +            transition: all 0.3s;
 +            font-family: inherit;
 +        }
 +
 +        .interval-training-app .answer-btn:hover {
 +            border-color: #4299e1;
 +            transform: translateY(-2px);
 +            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
 +        }
 +
 +        .interval-training-app .answer-btn.correct {
 +            background: #48bb78;
 +            color: white;
 +            border-color: #48bb78;
 +        }
 +
 +        .interval-training-app .answer-btn.incorrect {
 +            background: #f56565;
 +            color: white;
 +            border-color: #f56565;
 +        }
 +
 +        .interval-training-app .results {
 +            text-align: center;
 +            padding: 30px;
 +        }
 +
 +        .interval-training-app .score {
 +            font-size: 3em;
 +            font-weight: bold;
 +            color: #4299e1;
 +            margin-bottom: 20px;
 +        }
 +
 +        .interval-training-app .progress-bar {
 +            width: 100%;
 +            height: 10px;
 +            background: #e2e8f0;
 +            border-radius: 5px;
 +            overflow: hidden;
 +            margin: 20px 0;
 +        }
 +
 +        .interval-training-app .progress-fill {
 +            height: 100%;
 +            background: linear-gradient(90deg, #48bb78, #38a169);
 +            transition: width 0.5s ease;
 +        }
 +
 +        .interval-training-app .hidden {
 +            display: none !important;
 +        }
 +
 +        /* Responsive Design */
 +        @media (max-width: 768px) {
 +            .interval-training-app {
 +                padding: 10px;
 +            }
 +            
 +            .interval-training-app .checkbox-grid {
 +                grid-template-columns: 1fr;
 +            }
 +            
 +            .interval-training-app h1 {
 +                font-size: 2em;
 +            }
 +
 +            .interval-training-app .control-buttons {
 +                justify-content: center;
 +            }
 +        }
 +    </style>
 +</head>
 +<body>
 +    <div class="interval-training-app">
 +        <h1>🎵 Intervalltrainer 2</h1>
 +        
 +        <div id="setup" class="card">
 +            <div class="section">
 +                <h2>Intervalle auswählen</h2>
 +                <div class="control-buttons">
 +                    <button class="btn btn-secondary" onclick="selectAllIntervals()">Alle auswählen</button>
 +                    <button class="btn btn-secondary" onclick="deselectAllIntervals()">Alle abwählen</button>
 +                </div>
 +                <div class="checkbox-grid" id="intervals">
 +                    <div class="checkbox-item">
 +                        <input type="checkbox" id="prime" value="prime" checked>
 +                        <label for="prime">Prime</label>
 +                    </div>
 +                    <div class="checkbox-item">
 +                        <input type="checkbox" id="kleine-sekunde" value="kleine-sekunde" checked>
 +                        <label for="kleine-sekunde">Kleine Sekunde</label>
 +                    </div>
 +                    <div class="checkbox-item">
 +                        <input type="checkbox" id="grosse-sekunde" value="grosse-sekunde" checked>
 +                        <label for="grosse-sekunde">Große Sekunde</label>
 +                    </div>
 +                    <div class="checkbox-item">
 +                        <input type="checkbox" id="kleine-terz" value="kleine-terz" checked>
 +                        <label for="kleine-terz">Kleine Terz</label>
 +                    </div>
 +                    <div class="checkbox-item">
 +                        <input type="checkbox" id="grosse-terz" value="grosse-terz" checked>
 +                        <label for="grosse-terz">Große Terz</label>
 +                    </div>
 +                    <div class="checkbox-item">
 +                        <input type="checkbox" id="reine-quarte" value="reine-quarte" checked>
 +                        <label for="reine-quarte">Reine Quarte</label>
 +                    </div>
 +                    <div class="checkbox-item">
 +                        <input type="checkbox" id="tritonus" value="tritonus" checked>
 +                        <label for="tritonus">Tritonus</label>
 +                    </div>
 +                    <div class="checkbox-item">
 +                        <input type="checkbox" id="reine-quinte" value="reine-quinte" checked>
 +                        <label for="reine-quinte">Reine Quinte</label>
 +                    </div>
 +                    <div class="checkbox-item">
 +                        <input type="checkbox" id="kleine-sexte" value="kleine-sexte" checked>
 +                        <label for="kleine-sexte">Kleine Sexte</label>
 +                    </div>
 +                    <div class="checkbox-item">
 +                        <input type="checkbox" id="grosse-sexte" value="grosse-sexte" checked>
 +                        <label for="grosse-sexte">Große Sexte</label>
 +                    </div>
 +                    <div class="checkbox-item">
 +                        <input type="checkbox" id="kleine-septime" value="kleine-septime" checked>
 +                        <label for="kleine-septime">Kleine Septime</label>
 +                    </div>
 +                    <div class="checkbox-item">
 +                        <input type="checkbox" id="grosse-septime" value="grosse-septime" checked>
 +                        <label for="grosse-septime">Große Septime</label>
 +                    </div>
 +                    <div class="checkbox-item">
 +                        <input type="checkbox" id="reine-oktave" value="reine-oktave" checked>
 +                        <label for="reine-oktave">Reine Oktave</label>
 +                    </div>
 +                </div>
 +            </div>
 +
 +            <div class="section">
 +                <h2>Wiedergabeart</h2>
 +                <div class="radio-group">
 +                    <div class="radio-item">
 +                        <input type="radio" id="nacheinander-aufsteigend" name="playback" value="nacheinander-aufsteigend" checked>
 +                        <label for="nacheinander-aufsteigend">Nacheinander, aufsteigend</label>
 +                    </div>
 +                    <div class="radio-item">
 +                        <input type="radio" id="nacheinander-absteigend" name="playback" value="nacheinander-absteigend">
 +                        <label for="nacheinander-absteigend">Nacheinander, absteigend</label>
 +                    </div>
 +                    <div class="radio-item">
 +                        <input type="radio" id="simultan" name="playback" value="simultan">
 +                        <label for="simultan">Gleichzeitig (simultan)</label>
 +                    </div>
 +                </div>
 +            </div>
 +
 +            <div class="section">
 +                <h2>Schwierigkeitsgrad</h2>
 +                <div class="radio-group">
 +                    <div class="radio-item">
 +                        <input type="radio" id="einfach" name="difficulty" value="einfach" checked>
 +                        <label for="einfach">Einfach (alle Intervalle vom gleichen Startton)</label>
 +                    </div>
 +                    <div class="radio-item">
 +                        <input type="radio" id="fortgeschritten" name="difficulty" value="fortgeschritten">
 +                        <label for="fortgeschritten">Fortgeschritten (beliebige Starttöne)</label>
 +                    </div>
 +                </div>
 +            </div>
 +
 +            <div class="section">
 +                <h2>Prüfungsmodus</h2>
 +                <div class="radio-group">
 +                    <div class="radio-item">
 +                        <input type="radio" id="intervall-bestimmung" name="quiz-mode" value="intervall-bestimmung" checked>
 +                        <label for="intervall-bestimmung">Intervallbestimmung</label>
 +                    </div>
 +                    <div class="radio-item">
 +                        <input type="radio" id="zielton-bestimmung" name="quiz-mode" value="zielton-bestimmung">
 +                        <label for="zielton-bestimmung">Zieltonbestimmung</label>
 +                    </div>
 +                </div>
 +            </div>
 +
 +            <div style="text-align: center; margin-top: 30px;">
 +                <button class="btn btn-success" onclick="startQuiz()" style="font-size: 18px; padding: 15px 40px;">
 +                    🎯 Prüfung starten
 +                </button>
 +            </div>
 +        </div>
 +
 +        <div id="quiz" class="card quiz-container">
 +            <div class="question-info">
 +                <div>Frage <span id="current-question">1</span> von 10</div>
 +                <div class="progress-bar">
 +                    <div class="progress-fill" id="progress" style="width: 10%"></div>
 +                </div>
 +            </div>
 +
 +            <div class="audio-controls">
 +                <button class="play-btn" onclick="playInterval()" id="play-button">
 +                    ▶️
 +                </button>
 +                <div style="margin-top: 10px;">
 +                    <button class="btn btn-secondary" onclick="playInterval()">Noch einmal anhören</button>
 +                </div>
 +            </div>
 +
 +            <div id="question-content">
 +                <!-- Hier werden die Antwortoptionen eingefügt -->
 +            </div>
 +
 +            <div style="text-align: center; margin-top: 20px;" id="quiz-controls">
 +                <button class="btn btn-secondary hidden" onclick="retryAnswer()" id="retry-btn">
 +                    Noch einmal versuchen
 +                </button>
 +                <button class="btn btn-danger hidden" onclick="showCorrectAnswer()" id="show-answer-btn">
 +                    Lösung anzeigen
 +                </button>
 +                <button class="btn btn-primary hidden" onclick="nextQuestion()" id="next-btn">
 +                    Nächste Frage
 +                </button>
 +            </div>
 +        </div>
 +
 +        <div id="results" class="card quiz-container">
 +            <div class="results">
 +                <h2>🎉 Prüfung abgeschlossen!</h2>
 +                <div class="score" id="final-score">0/10</div>
 +                <div id="score-message"></div>
 +                <button class="btn btn-primary" onclick="resetQuiz()" style="margin-top: 20px;">
 +                    Neue Prüfung starten
 +                </button>
 +            </div>
 +        </div>
 +    </div>
 +
 +    <script>
 +        // Musikdaten mit den ursprünglichen MP3-URLs
 +        const notes = {
 +            'G3': { url: 'http://ericweber.de/file/i/4e040ccbd92100222.mp3', semitones: 0, german: 'g' },
 +            'Ab3': { url: 'http://ericweber.de/file/i/c84a0148556100222.mp3', semitones: 1, german: 'as' },
 +            'A3': { url: 'http://ericweber.de/file/i/7f46038f296100222.mp3', semitones: 2, german: 'a' },
 +            'Bb3': { url: 'http://ericweber.de/file/i/a1f10164275100222.mp3', semitones: 3, german: 'b' },
 +            'B3': { url: 'http://ericweber.de/file/i/a96e00d3c16100222.mp3', semitones: 4, german: 'h' },
 +            'C4': { url: 'http://ericweber.de/file/i/c0d500ffb35100222.mp3', semitones: 5, german: 'c\'' },
 +            'Db4': { url: 'http://ericweber.de/file/i/5a5b0edfc54100222.mp3', semitones: 6, german: 'des\'' },
 +            'D4': { url: 'http://ericweber.de/file/i/ed570c18b94100222.mp3', semitones: 7, german: 'd\'' },
 +            'Eb4': { url: 'http://ericweber.de/file/i/02a201b7473100222.mp3', semitones: 8, german: 'es\'' },
 +            'E4': { url: 'http://ericweber.de/file/i/3b7f0f44514100222.mp3', semitones: 9, german: 'e\'' },
 +            'F4': { url: 'http://ericweber.de/file/i/6386002cd33100222.mp3', semitones: 10, german: 'f\'' },
 +            'Gb4': { url: 'http://ericweber.de/file/i/2836075a732100222.mp3', semitones: 11, german: 'ges\'' },
 +            'G4': { url: 'http://ericweber.de/file/i/491206c1e72100222.mp3', semitones: 12, german: 'g\'' },
 +            'Ab4': { url: 'http://ericweber.de/file/i/1974081e836100222.mp3', semitones: 13, german: 'as\'' },
 +            'A4': { url: 'http://ericweber.de/file/i/78500985176100222.mp3', semitones: 14, german: 'a\'' },
 +            'Bb4': { url: 'http://ericweber.de/file/i/11eb09a9655100222.mp3', semitones: 15, german: 'b\'' },
 +            'B4': { url: 'http://ericweber.de/file/i/a6e70b6e195100222.mp3', semitones: 16, german: 'h\'' },
 +            'C5': { url: 'http://ericweber.de/file/i/70cf0832f15100222.mp3', semitones: 17, german: 'c\'\'' },
 +            'Db5': { url: 'http://ericweber.de/file/i/8b650789134100222.mp3', semitones: 18, german: 'des\'\'' },
 +            'D5': { url: 'http://ericweber.de/file/i/ea410612874100222.mp3', semitones: 19, german: 'd\'\'' },
 +            'Eb5': { url: 'http://ericweber.de/file/i/b2b8097a053100222.mp3', semitones: 20, german: 'es\'\'' },
 +            'E5': { url: 'http://ericweber.de/file/i/05b40bbd793100222.mp3', semitones: 21, german: 'e\'\'' },
 +            'F5': { url: 'http://ericweber.de/file/i/d39c08e1913100222.mp3', semitones: 22, german: 'f\'\'' },
 +            'Gb5': { url: 'http://ericweber.de/file/i/982c0f97312100222.mp3', semitones: 23, german: 'ges\'\'' },
 +            'G5': { url: 'http://ericweber.de/file/i/f9080e0ca52100222.mp3', semitones: 24, german: 'g\'\'' }
 +        };
 +
 +        const intervals = {
 +            'prime': { name: 'Prime', semitones: 0 },
 +            'kleine-sekunde': { name: 'Kleine Sekunde', semitones: 1 },
 +            'grosse-sekunde': { name: 'Große Sekunde', semitones: 2 },
 +            'kleine-terz': { name: 'Kleine Terz', semitones: 3 },
 +            'grosse-terz': { name: 'Große Terz', semitones: 4 },
 +            'reine-quarte': { name: 'Reine Quarte', semitones: 5 },
 +            'tritonus': { name: 'Tritonus', semitones: 6 },
 +            'reine-quinte': { name: 'Reine Quinte', semitones: 7 },
 +            'kleine-sexte': { name: 'Kleine Sexte', semitones: 8 },
 +            'grosse-sexte': { name: 'Große Sexte', semitones: 9 },
 +            'kleine-septime': { name: 'Kleine Septime', semitones: 10 },
 +            'grosse-septime': { name: 'Große Septime', semitones: 11 },
 +            'reine-oktave': { name: 'Reine Oktave', semitones: 12 }
 +        };
 +
 +        // Quiz-Status
 +        let currentQuestion = 0;
 +        let questions = [];
 +        let score = 0;
 +        let currentAnswer = null;
 +        let answered = false;
 +
 +        function selectAllIntervals() {
 +            const checkboxes = document.querySelectorAll('#intervals input[type="checkbox"]');
 +            checkboxes.forEach(cb => cb.checked = true);
 +        }
 +
 +        function deselectAllIntervals() {
 +            const checkboxes = document.querySelectorAll('#intervals input[type="checkbox"]');
 +            checkboxes.forEach(cb => cb.checked = false);
 +        }
 +
 +        function getSelectedIntervals() {
 +            const checkboxes = document.querySelectorAll('#intervals input[type="checkbox"]:checked');
 +            return Array.from(checkboxes).map(cb => cb.value);
 +        }
 +
 +        function getRandomNote() {
 +            const noteKeys = Object.keys(notes);
 +            return noteKeys[Math.floor(Math.random() * noteKeys.length)];
 +        }
 +
 +        function getNoteByName(noteName) {
 +            return Object.keys(notes).find(key => key === noteName);
 +        }
 +
 +        function generateQuestions() {
 +            const selectedIntervals = getSelectedIntervals();
 +            const difficulty = document.querySelector('input[name="difficulty"]:checked').value;
 +            const quizMode = document.querySelector('input[name="quiz-mode"]:checked').value;
 +            
 +            if (selectedIntervals.length === 0) {
 +                alert('Bitte wählen Sie mindestens ein Intervall aus.');
 +                return false;
 +            }
 +
 +            questions = [];
 +            const baseNote = 'C4'; // Startton für einfachen Modus
 +
 +            for (let i = 0; i < 10; i++) {
 +                const intervalType = selectedIntervals[Math.floor(Math.random() * selectedIntervals.length)];
 +                const interval = intervals[intervalType];
 +                
 +                let startNote;
 +                if (difficulty === 'einfach') {
 +                    startNote = baseNote;
 +                } else {
 +                    // Für fortgeschrittenen Modus: zufälligen Startton wählen, der das Intervall ermöglicht
 +                    const noteKeys = Object.keys(notes);
 +                    const maxStartIndex = noteKeys.length - 1 - Math.ceil(interval.semitones / 12) * 12;
 +                    startNote = noteKeys[Math.floor(Math.random() * Math.max(1, maxStartIndex))];
 +                }
 +
 +                const startSemitones = notes[startNote].semitones;
 +                let targetSemitones = startSemitones + interval.semitones;
 +                
 +                // Zielnote finden
 +                const targetNote = Object.keys(notes).find(key => notes[key].semitones === targetSemitones);
 +                
 +                if (targetNote) {
 +                    const question = {
 +                        intervalType: intervalType,
 +                        interval: interval,
 +                        startNote: startNote,
 +                        targetNote: targetNote,
 +                        quizMode: quizMode
 +                    };
 +
 +                    if (quizMode === 'zielton-bestimmung') {
 +                        question.wrongAnswers = generateWrongAnswers(targetNote);
 +                    }
 +
 +                    questions.push(question);
 +                }
 +            }
 +
 +            return questions.length === 10;
 +        }
 +
 +        function generateWrongAnswers(correctNote) {
 +            const noteKeys = Object.keys(notes);
 +            const wrongAnswers = [];
 +            const correctIndex = noteKeys.indexOf(correctNote);
 +            
 +            while (wrongAnswers.length < 4) {
 +                const randomIndex = Math.floor(Math.random() * noteKeys.length);
 +                const randomNote = noteKeys[randomIndex];
 +                if (randomNote !== correctNote && !wrongAnswers.includes(randomNote)) {
 +                    wrongAnswers.push(randomNote);
 +                }
 +            }
 +            
 +            return wrongAnswers;
 +        }
 +
 +        function startQuiz() {
 +            if (!generateQuestions()) {
 +                return;
 +            }
 +
 +            currentQuestion = 0;
 +            score = 0;
 +            
 +            document.getElementById('setup').style.display = 'none';
 +            document.getElementById('quiz').style.display = 'block';
 +            
 +            showQuestion();
 +        }
 +
 +        function showQuestion() {
 +            answered = false;
 +            const question = questions[currentQuestion];
 +            
 +            document.getElementById('current-question').textContent = currentQuestion + 1;
 +            document.getElementById('progress').style.width = ((currentQuestion + 1) / 10 * 100) + '%';
 +            
 +            const questionContent = document.getElementById('question-content');
 +            
 +            if (question.quizMode === 'intervall-bestimmung') {
 +                const selectedIntervals = getSelectedIntervals();
 +                questionContent.innerHTML = `
 +                    <h3 style="text-align: center; margin-bottom: 20px;">Welches Intervall hören Sie?</h3>
 +                    <div class="answer-options">
 +                        ${selectedIntervals.map(intervalType => 
 +                            `<button class="answer-btn" onclick="selectAnswer('${intervalType}')">${intervals[intervalType].name}</button>`
 +                        ).join('')}
 +                    </div>
 +                `;
 +            } else {
 +                const allAnswers = [question.targetNote, ...question.wrongAnswers];
 +                shuffleArray(allAnswers);
 +                
 +                questionContent.innerHTML = `
 +                    <h3 style="text-align: center; margin-bottom: 10px;">Startton: ${notes[question.startNote].german}</h3>
 +                    <h3 style="text-align: center; margin-bottom: 20px;">Welcher Zielton wird erreicht?</h3>
 +                    <div class="answer-options">
 +                        ${allAnswers.map(note => 
 +                            `<button class="answer-btn" onclick="selectAnswer('${note}')">${notes[note].german}</button>`
 +                        ).join('')}
 +                    </div>
 +                `;
 +            }
 +            
 +            document.getElementById('show-answer-btn').classList.add('hidden');
 +            document.getElementById('next-btn').classList.add('hidden');
 +            document.getElementById('retry-btn').classList.add('hidden');
 +        }
 +
 +        function shuffleArray(array) {
 +            for (let i = array.length - 1; i > 0; i--) {
 +                const j = Math.floor(Math.random() * (i + 1));
 +                [array[i], array[j]] = [array[j], array[i]];
 +            }
 +        }
 +
 +        function playInterval() {
 +            const question = questions[currentQuestion];
 +            const playback = document.querySelector('input[name="playback"]:checked').value;
 +            
 +            playIntervalNotes(question.startNote, question.targetNote, playback);
 +        }
 +
 +        function playIntervalNotes(startNote, targetNote, playback) {
 +            if (playback === 'simultan') {
 +                // Beide Töne exakt gleichzeitig mit Promise.all
 +                const audio1 = new Audio(notes[startNote].url);
 +                const audio2 = new Audio(notes[targetNote].url);
 +                
 +                // Sicherstellen, dass beide Audios geladen sind
 +                Promise.all([
 +                    new Promise(resolve => {
 +                        audio1.addEventListener('canplaythrough', resolve, { once: true });
 +                        audio1.load();
 +                    }),
 +                    new Promise(resolve => {
 +                        audio2.addEventListener('canplaythrough', resolve, { once: true });
 +                        audio2.load();
 +                    })
 +                ]).then(() => {
 +                    // Exakt gleichzeitig starten
 +                    audio1.currentTime = 0;
 +                    audio2.currentTime = 0;
 +                    audio1.play().catch(e => console.log('Audio 1 playback failed:', e));
 +                    audio2.play().catch(e => console.log('Audio 2 playback failed:', e));
 +                }).catch(e => {
 +                    console.log('Audio loading failed, fallback to simple play:', e);
 +                    // Fallback: einfaches gleichzeitiges Abspielen
 +                    playNote(startNote);
 +                    playNote(targetNote);
 +                });
 +            } else if (playback === 'nacheinander-aufsteigend') {
 +                playNote(startNote);
 +                setTimeout(() => playNote(targetNote), 800);
 +            } else if (playback === 'nacheinander-absteigend') {
 +                playNote(targetNote);
 +                setTimeout(() => playNote(startNote), 800);
 +            }
 +        }
 +
 +        function playNote(noteName) {
 +            const audio = new Audio(notes[noteName].url);
 +            audio.play().catch(e => console.log('Audio playback failed:', e));
 +            return audio;
 +        }
 +
 +        function selectAnswer(answer) {
 +            if (answered) return;
 +            
 +            answered = true;
 +            currentAnswer = answer;
 +            
 +            const question = questions[currentQuestion];
 +            let correctAnswer;
 +            
 +            if (question.quizMode === 'intervall-bestimmung') {
 +                correctAnswer = question.intervalType;
 +            } else {
 +                correctAnswer = question.targetNote;
 +            }
 +            
 +            const answerButtons = document.querySelectorAll('.answer-btn');
 +            
 +            if (answer === correctAnswer) {
 +                // Richtige Antwort
 +                score++;
 +                answerButtons.forEach(btn => {
 +                    if (btn.textContent === (question.quizMode === 'intervall-bestimmung'
 +                        intervals[answer].name : 
 +                        notes[answer].german)) {
 +                        btn.classList.add('correct');
 +                    }
 +                });
 +                
 +                setTimeout(() => {
 +                    nextQuestion();
 +                }, 1500);
 +            } else {
 +                // Falsche Antwort - Button rot markieren
 +                answerButtons.forEach(btn => {
 +                    if (btn.textContent === (question.quizMode === 'intervall-bestimmung'
 +                        intervals[answer].name : 
 +                        notes[answer].german)) {
 +                        btn.classList.add('incorrect');
 +                    }
 +                });
 +                
 +                // Optionen nach falscher Antwort anzeigen
 +                document.getElementById('retry-btn').classList.remove('hidden');
 +                document.getElementById('show-answer-btn').classList.remove('hidden');
 +            }
 +        }
 +
 +        function retryAnswer() {
 +            // Reset für neuen Versuch
 +            answered = false;
 +            currentAnswer = null;
 +            
 +            // Alle Button-Markierungen entfernen
 +            const answerButtons = document.querySelectorAll('.answer-btn');
 +            answerButtons.forEach(btn => {
 +                btn.classList.remove('correct', 'incorrect');
 +            });
 +            
 +            // Buttons wieder verstecken
 +            document.getElementById('retry-btn').classList.add('hidden');
 +            document.getElementById('show-answer-btn').classList.add('hidden');
 +        }
 +
 +        function showCorrectAnswer() {
 +            const question = questions[currentQuestion];
 +            let correctAnswer;
 +            
 +            if (question.quizMode === 'intervall-bestimmung') {
 +                correctAnswer = question.intervalType;
 +            } else {
 +                correctAnswer = question.targetNote;
 +            }
 +            
 +            const answerButtons = document.querySelectorAll('.answer-btn');
 +            answerButtons.forEach(btn => {
 +                if (btn.textContent === (question.quizMode === 'intervall-bestimmung'
 +                    intervals[correctAnswer].name : 
 +                    notes[correctAnswer].german)) {
 +                    btn.classList.add('correct');
 +                }
 +            });
 +            
 +            document.getElementById('retry-btn').classList.add('hidden');
 +            document.getElementById('show-answer-btn').classList.add('hidden');
 +            document.getElementById('next-btn').classList.remove('hidden');
 +        }
 +
 +        function nextQuestion() {
 +            currentQuestion++;
 +            
 +            if (currentQuestion < 10) {
 +                showQuestion();
 +            } else {
 +                showResults();
 +            }
 +        }
 +
 +        function showResults() {
 +            document.getElementById('quiz').style.display = 'none';
 +            document.getElementById('results').style.display = 'block';
 +            
 +            const percentage = Math.round((score / 10) * 100);
 +            document.getElementById('final-score').textContent = `${score}/10 (${percentage}%)`;
 +            
 +            let message;
 +            if (percentage >= 90) {
 +                message = "Ausgezeichnet! Sie haben ein sehr gutes Gehör für Intervalle! 🎵";
 +            } else if (percentage >= 70) {
 +                message = "Sehr gut! Mit etwas mehr Übung werden Sie noch besser! 🎶";
 +            } else if (percentage >= 50) {
 +                message = "Nicht schlecht! Weiter üben lohnt sich! 🎤";
 +            } else {
 +                message = "Noch viel Raum für Verbesserung. Übung macht den Meister! 🎼";
 +            }
 +            
 +            document.getElementById('score-message').innerHTML = `<p style="font-size: 18px; margin-top: 20px;">${message}</p>`;
 +        }
 +
 +        function resetQuiz() {
 +            document.getElementById('results').style.display = 'none';
 +            document.getElementById('setup').style.display = 'block';
 +            
 +            // Reset all form values
 +            currentQuestion = 0;
 +            score = 0;
 +            questions = [];
 +            currentAnswer = null;
 +            answered = false;
 +        }
 +    </script>
 +</body>
 +</html>