"; var popup = window.open('','','width='+width+',height='+height); popup.document.write(doc);}function playsfromga(){ var i = octaveselector.selectedIndex + 1; var label = 'C'+i+'-C'+(i+2); galog( 'Plays-from', label);}function meloga(){ var label, i = melochords.selectedIndex; switch(i) { case 0 : label = 'single'; break; case 1 : label = 'major'; break; case 2 : label = 'minor'; break; default: label = ''; } galog( 'Melochords', label);}function labelboxstyle(){var st = 'label:hover { background: #f7f7f7; }\n';st += 'label { background: #efefef; } \n';st += 'label:hover { cursor: pointer; }\n';st += 'label { display: inline-block; padding: 0.25em; margin: 0.25em; border: 1px solid #888; border-radius: 0.5em; }\n';st += '@keyframes redblink-frames { 0% { box-shadow: 0 0 0 0px rgba(255, 0, 0, 1); } 100% { box-shadow: 0 0 0 0.1em rgba(255, 0, 0, 0.2); } } \n';st += '.redblink { animation: redblink-frames 1s infinite; } \n';var style = newel('style');style.appendChild(document.createTextNode(st));return style;}function sustainbox(){ var ss = document.createElement('input'); ss.id = 'susbox'; ss.setAttribute("type", "checkbox"); ss.checked = true; ss.setAttribute('checked','checked'); ss.setAttribute('onchange','galog("sustain","sustain");'); var aa = document.createElement('label'); aa.appendChild(ss); aa.innerHTML += 'sustain'; return aa;}// there is a more recent belowpanel() functionfunction advancedpanel(a,b){ var chordpanel = document.createElement('fieldset'); chordpanel.style.display = 'inline-block'; chordpanel.style.border = 'none'; chordpanel.style.margin = '0.5em'; chordpanel.style.padding = '0'; var rechord = document.createElement('input'); rechord.type = 'checkbox'; rechord.id = 'rechord'; rechord.setAttribute('onchange','rechordonchange();'); chordpanel.appendChild(rechord); var CHORD = document.createElement('span'); CHORD.id = 'CHORDtext'; CHORD.innerHTML = 'CHORD'; chordpanel.appendChild(CHORD); var memorybuttons = document.createElement('div'); memorybuttons.style.display = 'none'; memorybuttons.id = 'memorybuttons'; memorybuttons.style.marginTop = '0.5em'; memorybuttons.style.position = 'relative'; memorybuttons.style.resize = 'both'; memorybuttons.style.overflow = 'auto'; memorybuttons.style.border = '1px dotted darkgray'; memorybuttons.style.minHeight = '7em'; memorybuttons.innerHTML = 'tick the CHORD and RECORD checkboxes on and off '+html+'
to create chord buttons and playback buttons here'; memorybuttons.setAttribute('ondrop',"drop(event)"); memorybuttons.setAttribute('ondragover',"allowDrop(event)"); memorybuttons.setAttribute('ontouchstart','preventZoom(event);'); memorybuttons.setAttribute('ontouchmove', 'event.preventDefault();'); var recordedsounds = document.createElement('textarea'); recordedsounds.id = 'recordedsounds'; recordedsounds.style.display = 'none'; var advbuttons = document.createElement('div'); advbuttons.style.textAlign = 'center'; advbuttons.appendChild(chordpanel); advbuttons.appendChild(recordpanel()); advbuttons.appendChild(savechordsform()); advbuttons.appendChild(loadchordsbutton()); advbuttons.appendChild(popupbutton()); var adv = document.createElement('div'); adv.id = 'advanced'; adv.style.display = 'none'; adv.appendChild(advbuttons); adv.appendChild(memorybuttons); adv.appendChild(recordedsounds); applynoselect(adv); return adv; }function triggerbutton(button,onaction){ var obaton = document.createElement('div'); obaton.appendChild(button.cloneNode()); var buttonhtml = obaton.innerHTML; var rex = new RegExp(onaction+'="[^"]+'); var r = rex.exec(buttonhtml)[0]; r = r.substr(onaction.length+2); r = r.replace(/"/g,'"'); r = r.replace('-click','-keypress'); eval(r);}function userkeydownup(k,downup){ var keysensors = document.querySelectorAll(".ks"); if (keysensors.length == 0) return true; for (var i=0; i
"; var popup = window.open('','','width='+width+',height='+height); popup.document.write(doc);}function octaves_selector_onchange(){markQWE();playsfromga();piano7loadall();}function octaves_selector(a,b){var se = document.createElement('select');se.id = 'octaveselector';se.style.margin = '0.5em';for (var i=1; i<=6; i++){var opt = document.createElement('option');//opt.text = 'computer keyboard plays from ' + 'C'+i+' to C'+(i+2);opt.text = 'Tab plays C'+i;se.add(opt);}se.selectedIndex = (a<=3 && b>=4) ? 2 : a-1;se.setAttribute('onchange', 'octaves_selector_onchange();');return se;}function isdesktop(){return window.innerWidth >= 800;}function pianopanel(a,b){ document.head.appendChild(buttonpianostyle()); document.body.onkeydown = keydown; document.body.onkeyup = keyup; var div = document.createElement('div'); div.id = 'pianokeyboardpanel'; var melo = document.createElement('select'); melo.id = 'melochords'; melo.style.margin = '0.5em'; var opt = document.createElement('option'); opt.text = 'single notes'; melo.add(opt); opt = document.createElement('option'); opt.text = 'major chords'; melo.add(opt); opt = document.createElement('option'); opt.text = 'minor chords'; melo.add(opt); melo.setAttribute('onchange','meloga();'); melo.style.display = 'none'; var octavesbutton = document.createElement('button'); octavesbutton.id = 'octavesbutton'; octavesbutton.className = 'przycisk'; octavesbutton.innerHTML = 'octaves'; octavesbutton.setAttribute('onclick','octavesPanel.style.display="block";'); if (isdesktop()) octavesbutton.style.display = 'none'; var spot = document.createElement('div'); spot.id = 'keyboardspot'; spot.style.clear = 'both'; //spot.style.marginTop = '0.5em'; spot.appendChild(klawiatura(a,b)); var box = document.createElement('input'); box.id = 'advancedbox'; box.checked = false; box.setAttribute("type", "checkbox"); box.setAttribute('onclick','advanced.style.display=(this.checked)?"block":"none";'); var advbox = document.createElement('span'); advbox.id = 'advbox'; advbox.appendChild(box); advbox.innerHTML += 'advanced'; advbox.style.whiteSpace = 'nowrap'; var toppanel = document.createElement('div'); toppanel.appendChild(octavespanel(a,b)); toppanel.appendChild(octavesbutton); toppanel.appendChild(melo); toppanel.appendChild(advbox); toppanel.appendChild(donate()); var klawa = newel('table'); klawa.style.width = '100%'; var tr = newel('tr'); klawa.appendChild(tr); var td1 = newel('td'), td2 = newel('td'), td3 = newel('td'); td1.style.width = '1em'; td3.style.width = '1em'; if (isdesktop()) { var bu = newel('button'); bu.innerHTML = '⤢'; bu.setAttribute('onclick','openpopup_2020_07_27();'); td3.appendChild(bu); td3.style.position = 'relative'; bu.style.position = 'absolute'; bu.style.top = '0'; var bu = newel('button'); bu.innerHTML = '+'; bu.setAttribute('onclick','higheroctave();markQWE();unfocus();'); td3.appendChild(bu); var bu = newel('button'); bu.innerHTML = '−'; bu.setAttribute('onclick','removehighestoctave();markQWE();unfocus();'); td3.appendChild(bu); var bu = newel('button'); bu.innerHTML = '+'; bu.setAttribute('onclick','loweroctave();markQWE();unfocus();'); td1.appendChild(bu); var bu = newel('button'); bu.innerHTML = '−'; bu.setAttribute('onclick','removelowestoctave();markQWE();unfocus();'); td1.appendChild(bu); tr.appendChild(td1); tr.appendChild(td2); tr.appendChild(td3); } else tr.appendChild(td2); td2.appendChild(spot); div.appendChild(toppanel); div.appendChild(klawa); div.appendChild(belowpanel(a,b)); applynoselect(div); return div;} function clear_memorybuttons(){el('memorybuttons').innerHTML = '';savebutton.disabled = true;update_bookmark_chords_button(false);}function clear_memorybuttons_button(){var bu = newel('button');bu.className = 'przycisk';bu.innerHTML = 'clear';bu.setAttribute('onclick','clear_memorybuttons();')return bu;}function belowpanel(a,b){ var chordpanel = document.createElement('label'); chordpanel.id = 'rechorder'; var rechord = document.createElement('input'); rechord.type = 'checkbox'; rechord.id = 'rechord'; rechord.setAttribute('onchange','rechordonchange();'); chordpanel.appendChild(rechord); var CHORD = document.createElement('span'); CHORD.id = 'CHORDtext'; CHORD.innerHTML = 'CHORD'; chordpanel.appendChild(CHORD); var memorybuttons = document.createElement('div'); memorybuttons.style.display = 'none'; memorybuttons.id = 'memorybuttons'; memorybuttons.style.marginTop = '0.5em'; memorybuttons.style.position = 'relative'; memorybuttons.style.resize = 'both'; memorybuttons.style.overflow = 'auto'; memorybuttons.style.border = '1px dotted darkgray'; memorybuttons.style.minHeight = '7em'; memorybuttons.style.textAlign = 'left'; memorybuttons.innerHTML = 'tick the CHORD and RECORD checkboxes on and off Our online piano can be played like a physical piano because we match the piano keyboard layout:white keys to the second row and black keys to the first row on the computer's keyboard. Check out our first music lesson:the names of the piano keys and their sound frequencies. with a definition and demonstration with a definition and demonstration with a definition and demonstration with a definition and demonstration Every physical computer keyboard allows you to play notes from two octaves between C3 to C5.The white keys are mapped to the second row of keys: Tab, Q, ..., [, ] and Backslash.The black keys are mapped to the first row of keys: 1, 2, ..., =, Backspace.For example, C3 is played by pressing Tab while C#3 is played by pressing 1 and D3 is played by pressing Q and so on.Note that B4 is played by pressing the backslash key, while the Enter key plays C5. If your laptop has a numeric keypad then the row of white keys is extended with new white keys after Backlash: 7, 8, 9, +, Enter.The new black keys on the first row will be /, * and -. If you have an external keyboard with a navigation cluster and a numeric keypad,then you can play three octaves from C3 to C6.The Delete key will play C5, Home - C#5, End - D5 and so on to 7 on the numpad being F5 and so on. The keys from the row A,S,D and the row Z,X,C are programmed to play white key chords for rich melodies.Moreover, with advanced options you can assign any user-defined chord or single note to any key of the computer keyboard.Tick the CHORD checkbox to indicate a chord on the piano keyboard and then check it off to create a custom-made chord button.This button will play your chord but it can also be configured to be associated with a computer keyboard key. You can record anything played by this virtual piano keyboard and play it back at will.To start and stop recording check and uncheck the box RECORD. A playback button will appear automatically.You can have many playback buttons: each with its own recording. You can even play back more than one recording at the same time while making another recording to combine them. Each recording can be downloaded as a MIDI file.Such a file can be played by Windows Media Player directly orit can be converted online for free to an mp3 file. First make a recording and then locate the button which plays this recording.Next click the settings icon beside the button.Then click the download audio button. Please donate if you find this feature useful.I had to buy a more expensive hosting service to be able to run the script which generates MIDI files.And generally I struggle to find the time to work on my virtual pianobecause the website brings so little money that I need to focus all my efforts on my job just to survive financially. Your recordings and your custom chords are stored as buttons which can be dragged around to shift position.You can save all your buttons as a text file to your hard drive and then load this file later.Each button can be renamed and configured to be triggered by any key from the computer keyboard.You can program your computer keyboard so that each key plays a custom chord or a playback recording and then save the layout for later. You can generate a link that encodes all the chords from your buttons.For example, this link encodes all the possible three-note C major chords between C3 and C5:https://www.apronus.com/music/flashpiano.htm?c=48-52-55_48-52-67_48-55-64_48-64-67_52-55-60_52-55-72_52-60-67_52-67-72_55-60-64_55-64-72_60-64-67_64-67-72The online piano will be able to play all these chords after an appropriate button is clicked. This is an online piano in the sense that it needs a live Internet connection to work.But there is an offline version available as a single HTML file that you can open in your browser without being connected to the Internet.Note that the offline version does not have certain features which require a connection.It won't save your work and you can't download audio files of your recordings.The better sound quality option is not available.You can use it offline for private personal use including in a school classroom or in a private class.Contact me directly if you are interested. You can load this online piano from the linkhttps://www.apronus.com/music/flashpiano.htm?solfege=1. The default sound files are optimized for speed of loading so that you can start playing the piano immediately without waiting for the sounds to load.However, this comes at the cost of reduced quality, which may be an issue when using external loudspeakers or headphones.Fortunately, you can optionally load better sounds if you need higher sound quality. You might also be interested in my virtual guitarthat plays all the major chords, minor chords, and dominant sevenths chords. In fact, it can play any chords at all.But more importantly, the notes on the fretboard are visualized on a separate virtual piano keyboard which serves to explain how the guitar worksto those who already understand the piano. I have the ambition to make it the most useful virtual piano online simulator in the world so I need to know what exactly my users expect when they play it.Please feel free to write any comments and remarks by using the email address displayed on theApronus.com homepage. Privacy Policy
to create chord buttons and playback buttons here'; memorybuttons.setAttribute('ondrop',"drop(event)"); memorybuttons.setAttribute('ondragover',"allowDrop(event)"); memorybuttons.setAttribute('ontouchstart','preventZoom(event);'); memorybuttons.setAttribute('ontouchmove', 'event.preventDefault();'); var recordedsounds = document.createElement('textarea'); recordedsounds.id = 'recordedsounds'; recordedsounds.style.display = 'none'; var advbuttons = document.createElement('div'); advbuttons.style.textAlign = 'center'; advbuttons.appendChild(chordpanel); advbuttons.appendChild(recordpanel()); advbuttons.appendChild(savechordsform()); advbuttons.appendChild(loadchordsbutton()); advbuttons.appendChild(popupbutton()); var membupanel = newel('div'); membupanel.id = 'membupanel'; membupanel.style.display = 'none'; membupanel.appendChild(bookmark_chords_button()); membupanel.appendChild(clear_memorybuttons_button()); var adv = document.createElement('div'); adv.id = 'advanced'; adv.style.textAlign = 'center'; adv.append(volumeControlPanel()); adv.appendChild(pno0x3_bettersound_button()); var se = octaves_selector(a,b); if (!isdesktop()) se.style.display = 'none'; adv.appendChild(se); advbuttons.style.display = 'inline-block'; var sus = sustainbox(); if (!isdesktop()) sus.style.display = 'none'; adv.appendChild(sus); adv.appendChild(advbuttons); adv.appendChild(memorybuttons); adv.appendChild(recordedsounds); adv.appendChild(membupanel); applynoselect(adv); adv.style.marginTop = '0.5em'; return adv; }function initpiano_in_pianoessence(){document.head.appendChild(labelboxstyle());if (isdesktop()) initpiano_in_div(pianoessence,2,5); else initpiano_in_div(pianoessence,3,4);}function unfocus(){document.activeElement.blur();}function appeal(visible){var div = newel('div'); div.id = 'Appeal';div.style.display = visible ? 'block' : 'none';div.style.textAlign = 'center';div.style.backgroundColor = '#ffa';div.style.backgroundColor = 'rgb(255,165,0)'; // orangediv.style.backgroundColor = 'rgb(255,165,0,0.3)';div.style.borderRadius = '0.5em';var a = "This website is in financial crisis. Please consider donating regularly to keep it functional.";div.innerHTML = a;var donatebutton = donate();donatebutton.style.display = 'inline-block';div.appendChild(donatebutton);return div;}function appeal_show(){if (el('adhor')) close_adhor('nogalog');if (el('skydiv')) close_skydiv('nogalog');el('Appeal').style.display = 'block';}function add_custom_memorybutton_chord(keys){function custom_memorybutton_chord(keys){function custom_chordbutton(id,keys){// keys is an array of integersfunction include_this(n){return ('|'+keys.join('|')+'|').indexOf('|'+n+'|') > -1;} var name = ''; var chordbuttonclick = "galog('Memorybutton', 'chordbutton-click');"; var onmousedown = chordbuttonclick + id+"button.style.transform='translateY(4px)';"; var onmouseup = id+"button.style.transform='none';"; for (var n=21; n<=109; n++) { //var key = document.getElementById('klawisz'+n); //if (key && key.style.transform == 'translateY(6px)') if (include_this(n)) { name += soundname(n,true); onmousedown += 'activatepianokey('+n+');'; onmouseup += 'releasepianokey('+n+');'; } } if (name == '') return null; var button = document.createElement('button'); button.id = id+'button'; button.className = 'chord'; button.innerHTML = name; if (g_touchscreen == false) button.setAttribute('onmousedown',onmousedown); else button.setAttribute('ontouchstart',onmousedown); if (g_touchscreen == false) button.setAttribute('onmouseup',onmouseup); else button.setAttribute('ontouchend',onmouseup); return button;} var id = 'b'+Math.floor(Math.random()*100000)+Math.floor(Math.random()*100000); id += 'c'; var button = custom_chordbutton(id,keys); if (button == null) return null; var edit = settingsicon(); //size in pixels edit.style.display = 'block'; edit.style.cursor = 'pointer'; edit.setAttribute('onclick','document.getElementById("'+id+'editor").style.display="inline-block";'); edit.setAttribute('draggable','false'); var buttonedit = document.createElement('table'); buttonedit.id = id; buttonedit.style.borderCollapse = 'collapse'; buttonedit.style.display = 'inline-block'; buttonedit.style.margin = '0.5em'; var tr = document.createElement('tr'); var td = document.createElement('td'); td.style.padding = '0'; td.appendChild(button); tr.appendChild(td); td = document.createElement('td'); td.style.padding = '0'; td.appendChild(horizontaleditor(id)); td.appendChild(edit); tr.appendChild(td); buttonedit.appendChild(tr); var dragdiv = document.createElement('div'); dragdiv.id = id + 'dragdiv'; dragdiv.style.display = 'inline-block'; dragdiv.appendChild(buttonedit); dragdiv.setAttribute('draggable','true'); dragdiv.setAttribute('ondragstart',"drag(event)"); applynoselect(dragdiv); savebutton.disabled = false; return dragdiv; }if (memorybuttons.innerHTML.charAt(0)=='t') memorybuttons.innerHTML = '';var button = custom_memorybutton_chord(keys);if (button) memorybuttons.appendChild(button);if (button) el('memorybuttons').style.display = 'block';if (button) update_bookmark_chords_button(true);if (button) membupanel.style.display = 'block';return button ? true : false;}function add_custom_chordbuttons_from_query(){var something = false;var query = location.search;if (query == '') return false;try { query = new URLSearchParams(query); } catch (error) { return false; }if (!query.has('c')) return false;var chords = query.get('c');chords = chords.split('_');if (chords.length == 0) return false;for (var i=0; i < chords.length; i++){var chord = chords[i];var keys = chord.split('-');if (keys.length == 0) return something;if (add_custom_memorybutton_chord(keys)) something = true;}if (something) update_bookmark_chords_button(true);return something;}function bookmark_chords_from_memorybuttons(){function chords_from_memorybuttons(){function keys_from_chordbutton(bu){var data = bu.getAttribute('onmousedown');var keys = [];for (var n=21; n<=109; n++) if (data.indexOf('activatepianokey('+n+');') > -1) keys.push(n);return keys.join('-');}var buttons = el('memorybuttons').querySelectorAll('button.chord');if (buttons.length == 0) return '';var chords = [];for (var i=0; i < buttons.length; i++) chords.push(keys_from_chordbutton(buttons[i]));return chords.join('_');}var chords = chords_from_memorybuttons();if (chords == '') return;var url = '?c=' + chords;history.pushState('chord','',url);}function bookmark_chords_button(){var bu = newel('button');bu.id = 'bookmarkchordsbutton';bu.innerHTML = 'bookmark chords';bu.className = 'przycisk';bu.disabled = true;var ga = 'galog("bookmark_chords","-");';bu.setAttribute('onclick','bookmark_chords_from_memorybuttons();'+ga);return bu;}function update_bookmark_chords_button(how){if (how === true) bookmarkchordsbutton.disabled = false;if (how === false) bookmarkchordsbutton.disabled = true;}function add_custom_memorybuttons_from_chord_array(arr){for (var i=0; i < arr.length; i++) add_custom_memorybutton_chord(arr[i]);}function klawisz_teclado(n,extraC){ function notenote(svg) { var div = document.createElement('div'); div.innerHTML = svg; div.style.position = 'absolute'; div.style.bottom = '10%'; return div; } var viewbox = "viewBox='0 0 50 16'"; var Do = ""; var Re = ""; var Mi = ""; var Fa = ""; var Sol = ""; var La = ""; var Si = ""; var button = document.createElement('button'); button.id = 'klawisz'+n; button.setAttribute('onmousedown', "presspianokey("+n+");"); button.setAttribute('ontouchstart', "presspianokey("+n+");"); button.setAttribute('onmouseup', "releasepianokey("+n+");"); button.setAttribute('ontouchend', "releasepianokey("+n+");"); button.setAttribute('onmouseleave', "releasepianokey("+n+");"); button.style.width = extraC ? '100%' : keywidth(n); button.style.userSelect = 'none'; button.style.outline = 'none'; if (!isblackkey(n)) { button.className = 'whitekeybutton'; button.style.height = '100%'; button.style.position = 'relative'; button.style.margin = '0'; button.style.padding = '0'; button.style.border = 'none'; button.style.borderRadius = '0 0 4px 4px'; button.style.cursor = 'pointer'; var napis = keywrite(n); napis.style.position = 'absolute'; napis.style.bottom = '0'; napis.style.left = '25%'; napis.style.width = '50%'; button.appendChild(napis); switch (n%12) { case 0 : button.appendChild(notenote(Do)); break;case 2 : button.appendChild(notenote(Re)); break;case 4 : button.appendChild(notenote(Mi)); break;case 5 : button.appendChild(notenote(Fa)); break;case 7 : button.appendChild(notenote(Sol)); break;case 9 : button.appendChild(notenote(La)); break;case 11 : button.appendChild(notenote(Si)); break; } return button; } button.className = 'blackkeybutton'; button.style.height = 2/3*100+'%'; button.style.margin = '0'; button.style.padding = '0'; button.style.outline = 'none'; button.style.border = 'none'; button.style.cursor = 'pointer'; button.style.position = 'absolute'; button.style.top = '0'; button.style.borderRadius = '0 0 3px 3px'; var inkey = document.createElement('fieldset'); inkey.className = 'blackinkey'; inkey.style.height = '88%'; inkey.style.margin = '0'; inkey.style.marginLeft = '8%'; inkey.style.marginRight = '8%'; inkey.style.padding = '0'; inkey.style.border = 'none'; inkey.style.outline = 'none'; inkey.style.background = 'inherit'; inkey.style.boxShadow = '0px 2px 1px 0px #777'; button.appendChild(inkey); return button;}// chord computationfunction chord_array_from_pitch_classes(a,b,chromas){const length = chromas.length;if (length == 0) return [];if (b-a+1 < length) return [];var ret = [];for (let n=a; n<=b; n++){let index = chromas.indexOf(n%12);if (index > -1){let head = [n];if (length == 1){ret.push(head);}else{let smaller = [];for (let i=0; i < length; i++) if (i != index) smaller.push(chromas[i]);let tails = chord_array_from_pitch_classes(n+1,b,smaller);for (let i=0; i < tails.length; i++){let chord = head.concat(tails[i]);if (chord.length == length) ret.push(chord);}}}}return ret;}// end of chord computation// 2021-07-27 pno0x3 piano soundsfunction pno0x3_init(){var pno0x3_pianosounds = [];for (var i=24; i<=108; i++) pno0x3_pianosounds[i] = null;function all_sounds_loaded(){for (var n=30; n<=96; n=n+3) if (pno0x3_pianosounds[n] == null) return false;return true;}function progress_percentage(){var n_decoded = 0;for (var n=30; n<=96; n=n+3) if (pno0x3_pianosounds[n] != null) n_decoded++;return Math.floor(100*n_decoded/23);}function progressbar(){var div = document.createElement('div');div.id = 'pno0x3_progressbar';div.innerHTML = 'Loading sounds. Please wait half a minute...';if (lang == 'ru') div.innerHTML = 'Загрузка звуков. Подождите полминуты...';if (lang == 'es') div.innerHTML = 'Cargando sonidos. Espere medio minuto...';div.style.position = 'fixed';div.style.width = '60%';div.style.left = '20vw';div.style.top = '10vh';div.style.backgroundColor = 'white';div.style.fontSize = '200%';div.style.padding = '0.5em';div.style.border = '0.5em solid #777';div.style.borderRadius = '0.5em';return div;}function updateprogressbar(){var a = document.getElementById('pno0x3_progressbar');var p = progress_percentage();a.style.backgroundImage = 'linear-gradient(to right, #ddd '+p+'%, white '+p+'%)';}function pno0x3_load(n){ var url = 'https://www.apronus.com/static/pno0x3-pianosounds/pno0'+n+'.mp3'; var request = new XMLHttpRequest(); request.open("GET", url, true); request.responseType = "arraybuffer"; request.onload = function() { audiocontext.decodeAudioData( request.response, function(buffer) { if (!buffer) { alert('error decoding file data: ' + url); return; } pno0x3_pianosounds[n] = buffer; console.log('Sound pno0'+n+' is ready.'); updateprogressbar(); if (all_sounds_loaded()) {playpianosound = pno0x3_playpianosound; // global function is overwrittenplaypiano7sound = function(n,delayInSeconds){ pno0x3_playpianosound(null,n,delayInSeconds); };pno0x3_init = function(){};console.log('All pno0x3 sounds are ready.');document.getElementById('pno0x3_progressbar').style.display = 'none'; } }, function(error) { console.error('decodeAudioData error', error); }); } request.onerror = function() { alert('BufferLoader: XHR error'); } request.send();}function pno0x3_playpianosound(context,n,delayInSeconds){function sourcestart(n,rate,volume,delayInSeconds){ if (audiocontext.state == 'suspended') audiocontext.resume(); var gainNode = audiocontext.createGain(); gainNode.gain.value = volume * volumeValue(); if (!susbox.checked) // no sustain { var duration = 0.6; // in seconds var start = audiocontext.currentTime + delayInSeconds; var stop = start + duration; gainNode.gain.setValueAtTime(volume, start); gainNode.gain.linearRampToValueAtTime(1, stop); gainNode.gain.linearRampToValueAtTime(0, stop+0.1); } var source = audiocontext.createBufferSource(); source.buffer = pno0x3_pianosounds[n]; source.playbackRate.value = rate; source.connect(gainNode); gainNode.connect(audiocontext.destination); source.start(audiocontext.currentTime + delayInSeconds);} delayInSeconds = delayInSeconds || 0; if (delayInSeconds > 0) setTimeout( "recordnow("+n+");" , delayInSeconds*1000); var volume; switch (n) { case 56: case 57: case 58: volume = 0.6; break; case 62: case 63: case 64: volume = 0.7; break; case 65: case 66: case 67: volume = 0.5; break; case 68: case 69: case 69: volume = 0.7; break; default: volume = 1; } if (n<=45) volume = 0.6; if (n<=38) volume = 0.4; if (n==38) sourcestart(36,Math.pow(2,2/12),volume,delayInSeconds); else if (n==39) { sourcestart(42,Math.pow(2,-3/12),volume,delayInSeconds); sourcestart(36,Math.pow(2,3/12),volume,delayInSeconds); } else if (n==40) sourcestart(42,Math.pow(2,-2/12),volume,delayInSeconds); else if (n>=96) { sourcestart(96,Math.pow(2,(n-96)/12),volume,delayInSeconds); } else if (n<30) { sourcestart(30,Math.pow(2,(n-30)/12),volume,delayInSeconds); } else switch (n%3) { case 0 : sourcestart(n,1,volume,delayInSeconds); break; case 1 : sourcestart(n-1,Math.pow(2,1/12),volume,delayInSeconds); break; case 2 : sourcestart(n+1,Math.pow(2,-1/12),volume,delayInSeconds); }}document.body.appendChild(progressbar());for (var n=30; n<=96; n=n+3) pno0x3_load(n);// Note that sound files for 24 and 27 exist but they are not loaded.//playpianosound = pno0x3_playpianosound;// this is executed by pno0x3_load after all sounds have been loaded}function pno0x3_bettersound_button(){var bu = document.createElement('button');bu.id = 'pno0x3_button';bu.className = 'przycisk';bu.innerHTML = 'better sound';bu.setAttribute('onclick','pno0x3_bettersound_button_clicked();');return bu;}function pno0x3_bettersound_button_clicked(){pno0x3_init();//pno0x3_button.style.display="none"; //desirable but makes the button disappear in popupgalog('betterSound','-');}function volumeValue(){const vc = el('volume_control');if (vc === null) return 2;return vc.value / 2.5; // from 0 to 10 converted to from 0 to 4}function volumeControlPanel(){const panel = newel('div');panel.style.display = 'inline-block';const lower = newel('button');lower.innerHTML = '-';lower.title = 'volume down';lower.setAttribute('onclick', `const v = parseInt(el('volume_control').value);el('volume_control').value = Math.max(0, v - 1);`);const higher = newel('button');higher.innerHTML = '+';higher.title = 'volume up';higher.setAttribute('onclick', `const v = parseInt(el('volume_control').value);el('volume_control').value = Math.min(10, v + 1);`);const val = newel('input');val.id = 'volume_control';val.type = 'text';val.setAttribute('value','5');val.value = '5';val.style.width = '2em';val.style.textAlign = 'center';val.setAttribute('onchange', `let v = parseInt(this.value);if (isNaN(v)) v = 5;v = Math.max(0, v);v = Math.min(v, 10);this.value = v;`);panel.append(lower, val, higher);return panel;}function uiget_pressedkey_list(){const keys = [];for (let n=21; n<=109; n++){const key = el('klawisz'+n);if (key && key.style.transform == 'translateY(6px)'){keys.push(n);}}return keys;}function areSetsEqual(set1, set2){ if (set1.size !== set2.size) return false; for (const element of set1) { if (!set2.has(element)) return false; } return true;}function recognize_chord(keys){const abstract_chord = new Set();for (const key of keys){abstract_chord.add(key % 12);}for (let root = 0; root <= 11; root++){const major = new Set( [root, (root+4)%12, (root+7)%12] );if (areSetsEqual(major, abstract_chord)){const chord = {};chord.structure = '' + root + '+4+3';chord.type = 'major';chord.nick = '';return chord;}const minor = new Set( [root, (root+3)%12, (root+7)%12] );if (areSetsEqual(minor, abstract_chord)){const chord = {};chord.structure = '' + root + '+3+4';chord.type = 'minor';chord.nick = 'm';return chord;}const diminished = new Set( [root, (root+3)%12, (root+6)%12] );if (areSetsEqual(diminished, abstract_chord)){const chord = {};chord.structure = '' + root + '+3+3';chord.type = 'diminished';chord.nick = 'dim';return chord;} const augmented = new Set([root, (root + 4) % 12, (root + 8) % 12]); if (areSetsEqual(augmented, abstract_chord)){ const chord = {}; chord.structure = '' + root + '+4+4'; chord.type = 'augmented'; chord.nick = 'aug'; return chord; } const dominant = new Set([root, (root + 4) % 12, (root + 7) % 12, (root + 10) % 12]); if (areSetsEqual(dominant, abstract_chord)) { const chord = {}; chord.structure = '' + root + '+4+3+3'; chord.type = 'dominant seventh'; chord.nick = '7'; return chord; }const major7Chord = new Set([root, (root + 4) % 12, (root + 7) % 12, (root + 11) % 12]);if (areSetsEqual(major7Chord, abstract_chord)) {const chord = {};chord.structure = '' + root + '+4+3+4';chord.type = 'major seventh';chord.nick = 'maj7';return chord;}const minor7Chord = new Set([root, (root + 3) % 12, (root + 7) % 12, (root + 10) % 12]);if (areSetsEqual(minor7Chord, abstract_chord)) {const chord = {};chord.structure = '' + root + '+3+4+3';chord.type = 'minor seventh';chord.nick = 'm7';return chord;}const augmented7Chord = new Set([root, (root + 4) % 12, (root + 8) % 12, (root + 10) % 12]);if (areSetsEqual(augmented7Chord, abstract_chord)) {const chord = {};chord.structure = '' + root + '+4+4+2';chord.type = 'augmented seventh';chord.nick = 'aug7';return chord;}const diminished7Chord = new Set([root, (root + 3) % 12, (root + 6) % 12, (root + 9) % 12]);if (areSetsEqual(diminished7Chord, abstract_chord)) {const chord = {};chord.structure = '' + root + '+3+3+3';chord.type = 'diminished seventh';chord.nick = 'o7';return chord;}const sus2Chord = new Set([root, (root + 2) % 12, (root + 7) % 12]);if (areSetsEqual(sus2Chord, abstract_chord)) {const chord = {};chord.structure = '' + root + '+2+5';chord.type = 'suspended second';chord.nick = 'sus2';return chord;}const sus4Chord = new Set([root, (root + 5) % 12, (root + 7) % 12]);if (areSetsEqual(sus4Chord, abstract_chord)) {const chord = {};chord.structure = '' + root + '+5+2';chord.type = 'suspended fourth';chord.nick = 'sus4';return chord;}const powerChord = new Set([root, (root + 7) % 12]);if (areSetsEqual(powerChord, abstract_chord)) {const chord = {};chord.structure = '' + root + '+7';chord.type = 'power chord';chord.nick = '5';return chord;}}const chord = {};chord.structure = Array.from(abstract_chord).join(',');chord.type = null;chord.nick = null;return chord;}function chord_name(chord){if (chord.type === null) return null;const root = parseInt(chord.structure.split('+')[0]);const type = chord.type;if (isblackkey(root)){const name1 = soundletter(root, 'sharp');const name2 = soundletter(root, null);return name1 + ' ' + type + ', ' + name2 + ' ' + type;}return soundletter(root) + ' ' + type;}function chord_nick(chord){if (chord.type === null) return null;const root = parseInt(chord.structure.split('+')[0]);const letter = soundletter(root, 'sharp');return letter + chord.nick;}function update_chord_info(){if (el('chordinfo') === null){const container = el('pianokeyboardpanel');const chordinfo = newel('div');chordinfo.id = 'chordinfo';container.prepend(chordinfo);container.style.position = 'relative';chordinfo.style.position = 'absolute';}el('chordinfo').innerHTML = '';const name = (chord_name(recognize_chord(uiget_pressedkey_list())));if (name === null) return;const outer = newel('div');const inner = newel('div');outer.style.textAlign = 'center';inner.style.display = 'inline-block';inner.innerHTML = name;inner.style.padding = '0.5em 1em 0.5em 1em';inner.style.borderRadius = '0.5em';inner.style.background = '#888';inner.style.color = 'white';outer.append(inner);el('chordinfo').append(outer);el('chordinfo').style.width = '100%';el('chordinfo').style.zIndex = '17';}function update_pressed_keys_markings(){const pressed_keys = uiget_pressedkey_list();for (let n = 21; n <= 109; n++){const key = el('klawisz'+n);if (key){if (pressed_keys.includes(n)){key.classList.add('marked_key');}else{key.classList.remove('marked_key');}}}}function el(a) { return document.getElementById(a); }function newel(a) { return document.createElement(a); }function number_button(type,n,numberit,sharp){var bu = newel('button');bu.id = type+'_button'+n;bu.setAttribute('onmousedown', type+"_button_down("+n+")");bu.setAttribute('ontouchstart', "event.preventDefault();"+type+"_button_down("+n+")");bu.innerHTML = soundname(n,sharp);var number = newel('div'); number.className = 'soundnumber';number.innerHTML = n;number.style.color = isblackkey(n) ? 'lightgray' : 'gray';number.style.marginTop = '7px';number.style.fontSize = 'smaller';if (numberit) bu.appendChild(number);bu.style.fontFamily = 'Arial';bu.style.outline = 'none'; bu.style.padding = '0'; bu.style.margin = '0';bu.style.width = '32px';bu.style.height = (numberit) ? '48px' : '32px';bu.style.cursor = 'pointer'; bu.style.border = '1px solid gray';if (isblackkey(n)) { bu.style.backgroundColor = 'black'; bu.style.color = 'white'; }else { bu.style.backgroundColor = 'white'; bu.style.color = 'black'; }return bu;}function number_buttons_row(type,number,a,b){var tr = newel('tr');for (var i=a; i<=b; i++){var td = newel('td'); td.style.padding = '0'; td.style.border = '0';var sharp = (i 60) return;var delayInSeconds = 0.3, delay = 100;for (var i=0; iplay single notes or chords with keyboard, mouse or touchscreen (sevenoctaves)
Names of Piano Keys
Major triads demo
Minor triads demo
Major scales demo
Natural minor scales demo
Use the computer keyboard to play the virtual piano
By default, the main part of the computer keyboard plays from C3 to C5 but you can change it to any other two octaves between C and C.You can use the selector below the piano keyboard or you can press the Left and Right arrows on the computer keyboard.Play any chords with the computer keyboard
Record and playback
Download audio files for your recordings
Save your work
Bookmark your chords
This online piano is available offline
Solfège is optional
Better sound quality
Chord recognition
You can check the CHORD checkbox to form any chord. This piano will recognize the following types of chords and display the full name:Virtual guitar
Feedback is welcome