diff --git a/html/assets/css/base.css b/html/assets/css/base.css
index b8d9ed7..09a6fee 100644
--- a/html/assets/css/base.css
+++ b/html/assets/css/base.css
@@ -25,4 +25,9 @@ h1 {
 #note-render {
     display: inline-block;
     margin: 0 auto;
-}
\ No newline at end of file
+}
+.checkboxes {
+    font-family: 'arial';
+    margin-top: 10px;
+    margin-bottom: 10px;
+}
diff --git a/html/assets/scripts/midi.js b/html/assets/scripts/midi.js
index abb3628..63d2097 100644
--- a/html/assets/scripts/midi.js
+++ b/html/assets/scripts/midi.js
@@ -10,7 +10,6 @@ window.addEventListener("load", function() {
 // press or unpress keyboard button
 function setKeyState(note, state) {
     let key = svgDoc.getElementById(String(note));
-    console.log(key);
     if (state) {
         key.style.fill = "red";
     } else if (keysB.includes(note)) {
@@ -50,13 +49,10 @@ function getMIDIMessage(midiMessage) {
         console.log(note);
         if (velocity == 0) {
             setKeyState(note, false);
+            task.changeKeyState(note,false);
         } else {
             setKeyState(note, true);
+            task.changeKeyState(note,true);
         }
     }
-
-    if (command == 144 && velocity != 0) {
-
-    } else if (command == 144 && velocity == 0)
-    console.log(command,note,velocity);
 }
\ No newline at end of file
diff --git a/html/assets/scripts/practice.js b/html/assets/scripts/practice.js
new file mode 100644
index 0000000..640b441
--- /dev/null
+++ b/html/assets/scripts/practice.js
@@ -0,0 +1,167 @@
+class Task {
+    /**
+     * 
+     * @param {Array}   keysig  list of keysignatures to use (int 0-11) where 0 = C || a, 1 = G || e ...
+     * @param {boolean} natural enable/disable naturals
+     * @param {boolean} sharp   enable/disable sharps
+     * @param {boolean} flat    enable/disable flats
+     * @param {boolean} chord   enable/disable chords (it's either chords or single notes)
+     * @param {boolean} extend  enable/disable notes above C6 and below C2
+     */
+    constructor() {
+        this.render  = new Notation();
+        this.retrieve_settings();
+
+        this.solution   = [];   // keys to solve current problem
+        this.activeKeys = [];   // currently pressed keys
+        this.active     = true; // true while task can be solved
+        this.success    = false;
+
+        this.generateTask();
+    }
+
+    generateTask() {
+        this.retrieve_settings();
+        if (this.chord) {
+            this.generateChord();
+        } else {
+            this.generateNote();
+        }
+    }
+
+    generateNote() {
+        let pickFrom = [];
+
+        // TODO: choose signature
+
+        // TODO: maybe weight note likelyhood
+
+        if (this.natural) {
+            pickFrom.push(...nat_values);
+            if (this.extend) {
+                pickFrom.push(...nat_values_ex);
+            }
+        }
+        if (this.sharp) {
+            pickFrom.push(...shp_values);
+            if (this.extend) {
+                pickFrom.push(...shp_values_ex);
+            }
+        }
+        if (this.flat) {
+            pickFrom.push(...flt_values);
+            if (this.extend) {
+                pickFrom.push(...flt_values_ex);
+            }
+        }
+
+        // pick from generated pool
+        var randomResult = Math.floor(Math.random() * pickFrom.length);
+        let chosenNote = pickFrom[randomResult];
+        this.solution = [chosenNote[1]];
+
+        let clef = "";
+
+        // choose clef
+        if (chosenNote[1] == 40) {
+            Math.random() < 0.5 ? clef = "bass" : clef = "treble";
+        } else if (chosenNote[1] < 40) {
+            clef = "bass";
+        } else {
+            clef = "treble";
+        }
+
+        this.solution = [chosenNote[1]];
+        this.render.set_notes([new Noteset(clef, [chosenNote[0]])]);
+    }
+
+    generateChord() {
+
+    }
+
+    on_keyStateChange() {
+        if (this.active) {
+            this.checkActiveKeys();
+        } else {
+            console.log("Can't continue, still keys pressed.");
+            return;
+        }
+        if (this.success) {
+            this.generateTask();
+        } else if (this.activeKeys.length == 0) {
+            this.active = true;
+        }
+    }
+
+    /**
+     * Keeps Track of pressed keys
+     * @param {number}  key 
+     * @param {boolean} state 
+     */
+    changeKeyState(key, state) {
+        if (state) {
+            // start new timer
+            if (this.activeKeys.length == 0) {
+                this.active = true;
+                this.starttime = Date.now();
+            }
+            this.activeKeys.push(key);
+        } else {
+            let index = this.activeKeys.indexOf(key);
+            if (index != -1) {
+                this.activeKeys.splice(index, 1);
+            }
+        }
+        this.on_keyStateChange()
+    }
+
+    /**
+     * Checks if activeKeys fulfill current task
+     */
+    checkActiveKeys() {
+        this.activeKeys.forEach( key => {
+            if (!(key in this.solution)) {
+                this.result_fail();
+                return;
+            }
+        });
+        if (this.activeKeys.length == this.solution.length) {
+            if (Date.now() - this.starttime <= 500) {
+                this.result_success();
+                return;
+            } else {
+                this.result_fail();
+                return;
+            }
+        }
+    }
+
+    result_fail() {
+        console.log("Wrong!");
+        this.active = false;
+    }
+
+    result_success() {
+        console.log("Correct!");
+        this.solution = [];
+        this.active   = false;
+        this.success  = true;
+    }
+
+    retrieve_settings() {
+        let cbx_naturals = document.getElementById("naturals");
+        let cbx_sharps   = document.getElementById("sharps");
+        let cbx_flats    = document.getElementById("flats");
+        let cbx_extended = document.getElementById("extended");
+        
+        this.keysig  = [0];
+        this.natural = cbx_naturals.checked;
+        this.sharp   = cbx_sharps.checked;
+        this.flat    = cbx_flats.checked;
+        this.chord   = false;
+        this.extend  = cbx_extended.checked;
+    }
+}
+
+// Starts the task loop
+var task = new Task();
diff --git a/html/assets/scripts/render.js b/html/assets/scripts/render.js
index 48e793e..21fc3fa 100644
--- a/html/assets/scripts/render.js
+++ b/html/assets/scripts/render.js
@@ -2,14 +2,44 @@ const { Renderer, Stave, StaveNote, Voice, Formatter, TickContext } = Vex.Flow;
 
 class Notation {
     constructor() {
-        // Create an SVG renderer and attach it to the DIV element
-        this.div = document.getElementById("note-render");
-        this.renderer = new Renderer(this.div, Renderer.Backends.SVG);
+        // init notelist
+        this.notesTop    = [];
+        this.notesBottom = [];
 
-        // Configure the rendering context.
-        this.renderer.resize(321, 500);
-        this.ctx = this.renderer.getContext();
+        // create voice
+        this.voiceTop    = new Vex.Flow.Voice({num_beats: 4, beat_value: 4, resolution: Vex.Flow.RESOLUTION});
+        this.voiceBottom = new Vex.Flow.Voice({num_beats: 4, beat_value: 4, resolution: Vex.Flow.RESOLUTION});
 
+        this.draw();
+    }
+    /**
+     * Takes list of notes ex: [{clef: "bass/treble", keys: ["c/4,"e/4"], duration: "w"},{clef: "bass/treble", keys: ["c/4,"e/4"], duration: "w"}]
+     * @param {Array[Noteset]} notes 
+     */
+    set_notes(to_set) {
+        // create voice
+        this.voiceTop    = new Vex.Flow.Voice({num_beats: 4, beat_value: 4, resolution: Vex.Flow.RESOLUTION});
+        this.voiceBottom = new Vex.Flow.Voice({num_beats: 4, beat_value: 4, resolution: Vex.Flow.RESOLUTION});
+        //this.voiceTop.tickables    = [];
+        //this.voiceBottom.tickables = [];
+
+        this.notesTop    = [];
+        this.notesBottom = [];
+
+        to_set.forEach( note => {
+            if (note.clef == "treble") {
+                this.notesTop.push(note.staveNote);
+            } else {
+                this.notesBottom.push(note.staveNote);
+            }
+        });
+
+        this.voiceTop.addTickables(this.notesTop);
+        this.voiceBottom.addTickables(this.notesBottom);
+        this.draw();
+    }
+
+    draw() {
         // Create the staves 
         this.topStaff = new Vex.Flow.Stave(20, 100, 300);
         this.bottomStaff = new Vex.Flow.Stave(20, 200, 300);
@@ -22,49 +52,17 @@ class Notation {
         this.brace     = new Vex.Flow.StaveConnector(this.topStaff, this.bottomStaff).setType(3); // 3 = brace
         this.lineLeft  = new Vex.Flow.StaveConnector(this.topStaff, this.bottomStaff).setType(1);
         this.lineRight = new Vex.Flow.StaveConnector(this.topStaff, this.bottomStaff).setType(6);
+        
+        // Create an SVG renderer and attach it to the DIV element
+        this.div = document.getElementById("note-render");
+        this.div.innerHTML = "";
 
-        // create voice
-        this.voiceTop    = new Vex.Flow.Voice({num_beats: 4, beat_value: 4, resolution: Vex.Flow.RESOLUTION});
-        this.voiceBottom = new Vex.Flow.Voice({num_beats: 4, beat_value: 4, resolution: Vex.Flow.RESOLUTION});
+        this.renderer = new Renderer(this.div, Renderer.Backends.SVG);
 
-        // init notelist
-        this.notesTop    = [];
-        this.notesBottom = [];
+        // Configure the rendering context.
+        this.renderer.resize(321, 500);
+        this.ctx = this.renderer.getContext();
 
-        this.draw();
-    }
-    /**
-     * Takes list of notes ex: [{clef: "bass/treble", keys: ["c/4,"e/4"], duration: "w"},{clef: "bass/treble", keys: ["c/4,"e/4"], duration: "w"}]
-     * @param {*} notes 
-     */
-    set_notes(to_set) {
-        this.voiceTop.tickables    = [];
-        this.voiceBottom.tickables = [];
-
-        this.notesTop    = [];
-        this.notesBottom = [];
-
-        to_set.forEach( note => {
-            if (note.clef == "treble") {
-                this.notesTop.push(new Vex.Flow.StaveNote(note));
-            } else {
-                this.notesBottom.push(new Vex.Flow.StaveNote(note));
-            }
-        });
-
-        for (let note of this.notesTop) {
-            note.x_shift = 100;
-        }
-        for (let note of this.notesBottom) {
-            note.x_shift = 100;
-        }
-
-        this.voiceTop.addTickables(this.notesTop);
-        this.voiceBottom.addTickables(this.notesBottom);
-        this.draw();
-    }
-
-    draw() {
         // draw background
         this.topStaff.setContext(this.ctx).draw();
         this.bottomStaff.setContext(this.ctx).draw();
@@ -86,12 +84,26 @@ class Notation {
 
 class Noteset {
     // syntax for notes: https://github.com/0xfe/vexflow/blob/master/src/tables.ts
+    /**
+     * 
+     * @param {String}        clef bass or treble
+     * @param {Array[String]} keys array of string
+     */
     constructor(clef, keys) {
         this.clef     = clef;
         this.keys     = keys;
-        this.duration = "w";
+        this.staveNote = new StaveNote({clef: clef, keys: keys, duration: "w"});
+        this.addAccidentals();
+    }
+    addAccidentals() {
+        for (var i=0; i < this.keys.length; i++) {
+            if (this.keys[i].includes("b")) {
+                this.staveNote.addModifier(new Vex.Flow.Accidental("b"),i)            
+            }
+            if (this.keys[i].includes("#")) {
+                this.staveNote.addModifier(new Vex.Flow.Accidental("#"),i);
+            }
+        }
+        //this.staveNote.setXShift(80);
     }
 }
-
-notator = new Notation();
-notator.set_notes([new Noteset("treble",["c/5","c/6"]),new Noteset("bass",["c/3"])]);
diff --git a/html/index.html b/html/index.html
index 50b46bb..27b574f 100644
--- a/html/index.html
+++ b/html/index.html
@@ -7,6 +7,12 @@
 <body>
     <div class="container">
         <div id="note-render"></div>
+        <div class="checkboxes">
+            <input type="checkbox" id="naturals" checked><label for="naturals">Natural</label>
+            <input type="checkbox" id="sharps"><label for="sharps">Sharps</label>
+            <input type="checkbox" id="flats"><label for="flats">Flats</label>
+            <input type="checkbox" id="extended"><label for="extended">Extended</label>
+        </div>
         <object id="piano" data="assets/img/piano-keyboard.svg" type="image/svg+xml" width="100%" type="image/svg+xml"></object>
     </div>
     <script src="https://cdn.jsdelivr.net/npm/vexflow@4.0.3/build/cjs/vexflow.js"></script>