{"action":"created","comment":{"url":"https://api.github.com/repos/GoogleChrome/omnitone/pulls/comments/102983708","pull_request_review_id":23756799,"id":102983708,"diff_hunk":"@@ -0,0 +1,162 @@\n+<!--\n+  Copyright 2016 Google Inc. All Rights Reserved.\n+  Licensed under the Apache License, Version 2.0 (the \"License\");\n+  you may not use this file except in compliance with the License.\n+  You may obtain a copy of the License at\n+\n+      http://www.apache.org/licenses/LICENSE-2.0\n+\n+  Unless required by applicable law or agreed to in writing, software\n+  distributed under the License is distributed on an \"AS IS\" BASIS,\n+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+  See the License for the specific language governing permissions and\n+  limitations under the License.\n+-->\n+<!DOCTYPE html>\n+<html>\n+<head>\n+  <meta charset=\"utf-8\">\n+  <title>A Simple Demo: Omnitone with Headtracking</title>\n+  <script src=\"../build/omnitone.min.js\"></script>\n+  <style>\n+    h2 {\n+      font-family: sans-serif; \n+    }\n+\n+    button {\n+      width: 120px;\n+      height: 24px;\n+      font-weight: bold;\n+    }\n+\n+    select {\n+      width: 120px;\n+      font-size: 24px;\n+    }\n+  </style>\n+</head>\n+<body>\n+  <h2>Select the sound source to play.</h2>\n+  <h2>Use headphones for the full-sphere surround sound.</h2>\n+  <p id=\"rotation\">Please connect a gamepad (or a headtracker emulating a gamepad) to enable an 3D audio playback that considers your head rotations.</p>\n+  <br>\n+  <select id=\"eSelectSource\" name=\"dropdown\" disabled>\n+    <option value=\"speech\" selected=\"selected\">Speech</option>\n+    <option value=\"warbird\">Airplanes</option>\n+  </select>\n+  <button id=\"eButtonPlayback\" disabled>Play</button>\n+\n+  <script>\n+    var audioSources = {\n+      'speech': 'resources/4ch_B_FuMaNorm_FuMaOrd_speech.wav',\n+      'warbird': 'resources/jlwarbirds3.amb'\n+    };\n+\n+    var buttonPlayback, selectSource;\n+    var yaw, pitch, roll;\n+\n+    window.addEventListener('load', function () {\n+\n+      // Set up the context and the audio element.\n+      var audioContext = new AudioContext();\n+      var audioElement = document.createElement('audio');\n+      audioElement.loop = true;\n+      audioElement.crossOrigin = 'anonymous';\n+      audioElement.src = audioSources['speech'];\n+\n+      // Create a decoder.\n+      var decoder = Omnitone.createFOADecoder(audioContext, audioElement, {\n+        // The example audio is in the FuMa ordering (W,X,Y,Z). So remap the\n+        // channels to the ACN format.\n+        channelMap: [0, 3, 1, 2]\n+      });\n+\n+      // Handles UI.\n+      buttonPlayback = document.getElementById('eButtonPlayback');\n+      selectSource = document.getElementById('eSelectSource');\n+\n+      buttonPlayback.onclick = function (event) {\n+        if (event.target.textContent === 'Play') {\n+          event.target.textContent = 'Pause';\n+          audioElement.play();\n+        } else {\n+          event.target.textContent = 'Play';\n+          audioElement.pause();\n+        }\n+      };\n+\n+      selectSource.onchange = function (event) {\n+        audioElement.src = audioSources[event.target.value];\n+        audioElement.load();\n+        if (buttonPlayback.textContent === 'Pause')\n+          audioElement.play();\n+      };\n+\n+      var rotator;\n+      \n+      // Initialize the decoder and activate the button when ready.\n+      decoder.initialize().then(function () {\n+        buttonPlayback.disabled = false;\n+        selectSource.disabled = false;\n+        rotator = Omnitone.createFOARotator(audioContext);\n+        window.requestAnimationFrame(runAnimation);\n+      }, function (onInitializationError) {\n+        console.error(onInitializationError);\n+      });\n+\n+      var textRotation = document.getElementById('rotation');\n+\n+      function runAnimation() {\n+\n+        // look for a Gamepad and check, whether is has changed it axes values.\n+        var gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);\n+        var changed = false;\n+        for (var i = 0; i < gamepads.length; ++i) {\n+          var pad = gamepads[i];\n+          if (pad != null) {\n+            if (roll != pad.axes[2] || pitch != pad.axes[1] || yaw != pad.axes[0]) {\n+              changed = true;\n+              yaw = pad.axes[0];\n+              pitch = pad.axes[1];\n+              roll = pad.axes[2];\n+              textRotation.innerHTML = \"yaw \" + Math.round(yaw * 180) \n+                + \" pitch \" + Math.round(pitch * 180) \n+                + \" roll \" + Math.round(roll * 180);\n+            }\n+            break;\n+          }\n+        }\n+\n+        if (changed) {\n+          // from http://mathworld.wolfram.com/EulerAngles.html\n+          // down is back\n+          \n+          var phi = yaw * Math.PI; \n+          // 1. the first rotation is by an angle phi about the z-axis using D,\n+          \n+          var theta = pitch * Math.PI; \n+          // the second rotation is by an angle theta in [0,pi] about the former x-axis (now x^') using C, and\n+          \n+          var psi = roll * Math.PI;   \n+          //3. the third rotation is by an angle psi about the former z-axis (now z^') using B.\n+\n+          rotator.setRotationMatrix([\n+            Math.cos(psi) * Math.cos(phi) - Math.cos(theta) * Math.sin(phi) * Math.sin(psi),\n+            Math.cos(psi) * Math.sin(phi) + Math.cos(theta) * Math.cos(phi) * Math.sin(psi),\n+            Math.sin(psi) * Math.sin(theta),\n+            -Math.sin(psi) * Math.cos(phi) - Math.cos(theta) * Math.sin(phi) * Math.cos(psi),\n+            -Math.sin(psi) * Math.sin(phi) + Math.cos(theta) * Math.cos(phi) * Math.cos(psi),\n+            Math.cos(psi) * Math.sin(theta),\n+            Math.sin(theta) * Math.sin(phi),\n+            -Math.sin(theta) * Math.cos(phi),\n+            Math.cos(theta)\n+          ]);\n+          decoder.setRotationMatrix(rotator.getRotationMatrix());","path":"examples/gamepad.html","position":154,"original_position":154,"commit_id":"fc2adb22c81b89be140cba52ac7e7b79a5d128ef","original_commit_id":"fc2adb22c81b89be140cba52ac7e7b79a5d128ef","user":{"login":"hoch","id":676891,"avatar_url":"https://avatars.githubusercontent.com/u/676891?v=3","gravatar_id":"","url":"https://api.github.com/users/hoch","html_url":"https://github.com/hoch","followers_url":"https://api.github.com/users/hoch/followers","following_url":"https://api.github.com/users/hoch/following{/other_user}","gists_url":"https://api.github.com/users/hoch/gists{/gist_id}","starred_url":"https://api.github.com/users/hoch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hoch/subscriptions","organizations_url":"https://api.github.com/users/hoch/orgs","repos_url":"https://api.github.com/users/hoch/repos","events_url":"https://api.github.com/users/hoch/events{/privacy}","received_events_url":"https://api.github.com/users/hoch/received_events","type":"User","site_admin":false},"body":"... and remove this line.","created_at":"2017-02-24T16:56:47Z","updated_at":"2017-02-24T16:57:40Z","html_url":"https://github.com/GoogleChrome/omnitone/pull/33#discussion_r102983708","pull_request_url":"https://api.github.com/repos/GoogleChrome/omnitone/pulls/33","_links":{"self":{"href":"https://api.github.com/repos/GoogleChrome/omnitone/pulls/comments/102983708"},"html":{"href":"https://github.com/GoogleChrome/omnitone/pull/33#discussion_r102983708"},"pull_request":{"href":"https://api.github.com/repos/GoogleChrome/omnitone/pulls/33"}}},"pull_request":{"url":"https://api.github.com/repos/GoogleChrome/omnitone/pulls/33","id":106380282,"html_url":"https://github.com/GoogleChrome/omnitone/pull/33","diff_url":"https://github.com/GoogleChrome/omnitone/pull/33.diff","patch_url":"https://github.com/GoogleChrome/omnitone/pull/33.patch","issue_url":"https://api.github.com/repos/GoogleChrome/omnitone/issues/33","number":33,"state":"open","locked":false,"title":"Added real head tracking using a gamepad device","user":{"login":"hoene","id":7519642,"avatar_url":"https://avatars.githubusercontent.com/u/7519642?v=3","gravatar_id":"","url":"https://api.github.com/users/hoene","html_url":"https://github.com/hoene","followers_url":"https://api.github.com/users/hoene/followers","following_url":"https://api.github.com/users/hoene/following{/other_user}","gists_url":"https://api.github.com/users/hoene/gists{/gist_id}","starred_url":"https://api.github.com/users/hoene/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hoene/subscriptions","organizations_url":"https://api.github.com/users/hoene/orgs","repos_url":"https://api.github.com/users/hoene/repos","events_url":"https://api.github.com/users/hoene/events{/privacy}","received_events_url":"https://api.github.com/users/hoene/received_events","type":"User","site_admin":false},"body":"Gamepads are the easiest way of getting rotation data into the browser...\r\n","created_at":"2017-02-15T19:20:46Z","updated_at":"2017-02-24T16:57:40Z","closed_at":null,"merged_at":null,"merge_commit_sha":"96736efdf870336814babec549b948e7ce098794","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/GoogleChrome/omnitone/pulls/33/commits","review_comments_url":"https://api.github.com/repos/GoogleChrome/omnitone/pulls/33/comments","review_comment_url":"https://api.github.com/repos/GoogleChrome/omnitone/pulls/comments{/number}","comments_url":"https://api.github.com/repos/GoogleChrome/omnitone/issues/33/comments","statuses_url":"https://api.github.com/repos/GoogleChrome/omnitone/statuses/fc2adb22c81b89be140cba52ac7e7b79a5d128ef","head":{"label":"hoene:master","ref":"master","sha":"fc2adb22c81b89be140cba52ac7e7b79a5d128ef","user":{"login":"hoene","id":7519642,"avatar_url":"https://avatars.githubusercontent.com/u/7519642?v=3","gravatar_id":"","url":"https://api.github.com/users/hoene","html_url":"https://github.com/hoene","followers_url":"https://api.github.com/users/hoene/followers","following_url":"https://api.github.com/users/hoene/following{/other_user}","gists_url":"https://api.github.com/users/hoene/gists{/gist_id}","starred_url":"https://api.github.com/users/hoene/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hoene/subscriptions","organizations_url":"https://api.github.com/users/hoene/orgs","repos_url":"https://api.github.com/users/hoene/repos","events_url":"https://api.github.com/users/hoene/events{/privacy}","received_events_url":"https://api.github.com/users/hoene/received_events","type":"User","site_admin":false},"repo":{"id":82096920,"name":"omnitone","full_name":"hoene/omnitone","owner":{"login":"hoene","id":7519642,"avatar_url":"https://avatars.githubusercontent.com/u/7519642?v=3","gravatar_id":"","url":"https://api.github.com/users/hoene","html_url":"https://github.com/hoene","followers_url":"https://api.github.com/users/hoene/followers","following_url":"https://api.github.com/users/hoene/following{/other_user}","gists_url":"https://api.github.com/users/hoene/gists{/gist_id}","starred_url":"https://api.github.com/users/hoene/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hoene/subscriptions","organizations_url":"https://api.github.com/users/hoene/orgs","repos_url":"https://api.github.com/users/hoene/repos","events_url":"https://api.github.com/users/hoene/events{/privacy}","received_events_url":"https://api.github.com/users/hoene/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/hoene/omnitone","description":"Spatial Audio on the Web.","fork":true,"url":"https://api.github.com/repos/hoene/omnitone","forks_url":"https://api.github.com/repos/hoene/omnitone/forks","keys_url":"https://api.github.com/repos/hoene/omnitone/keys{/key_id}","collaborators_url":"https://api.github.com/repos/hoene/omnitone/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/hoene/omnitone/teams","hooks_url":"https://api.github.com/repos/hoene/omnitone/hooks","issue_events_url":"https://api.github.com/repos/hoene/omnitone/issues/events{/number}","events_url":"https://api.github.com/repos/hoene/omnitone/events","assignees_url":"https://api.github.com/repos/hoene/omnitone/assignees{/user}","branches_url":"https://api.github.com/repos/hoene/omnitone/branches{/branch}","tags_url":"https://api.github.com/repos/hoene/omnitone/tags","blobs_url":"https://api.github.com/repos/hoene/omnitone/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/hoene/omnitone/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/hoene/omnitone/git/refs{/sha}","trees_url":"https://api.github.com/repos/hoene/omnitone/git/trees{/sha}","statuses_url":"https://api.github.com/repos/hoene/omnitone/statuses/{sha}","languages_url":"https://api.github.com/repos/hoene/omnitone/languages","stargazers_url":"https://api.github.com/repos/hoene/omnitone/stargazers","contributors_url":"https://api.github.com/repos/hoene/omnitone/contributors","subscribers_url":"https://api.github.com/repos/hoene/omnitone/subscribers","subscription_url":"https://api.github.com/repos/hoene/omnitone/subscription","commits_url":"https://api.github.com/repos/hoene/omnitone/commits{/sha}","git_commits_url":"https://api.github.com/repos/hoene/omnitone/git/commits{/sha}","comments_url":"https://api.github.com/repos/hoene/omnitone/comments{/number}","issue_comment_url":"https://api.github.com/repos/hoene/omnitone/issues/comments{/number}","contents_url":"https://api.github.com/repos/hoene/omnitone/contents/{+path}","compare_url":"https://api.github.com/repos/hoene/omnitone/compare/{base}...{head}","merges_url":"https://api.github.com/repos/hoene/omnitone/merges","archive_url":"https://api.github.com/repos/hoene/omnitone/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/hoene/omnitone/downloads","issues_url":"https://api.github.com/repos/hoene/omnitone/issues{/number}","pulls_url":"https://api.github.com/repos/hoene/omnitone/pulls{/number}","milestones_url":"https://api.github.com/repos/hoene/omnitone/milestones{/number}","notifications_url":"https://api.github.com/repos/hoene/omnitone/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/hoene/omnitone/labels{/name}","releases_url":"https://api.github.com/repos/hoene/omnitone/releases{/id}","deployments_url":"https://api.github.com/repos/hoene/omnitone/deployments","created_at":"2017-02-15T19:15:29Z","updated_at":"2017-02-15T19:15:30Z","pushed_at":"2017-02-24T16:25:40Z","git_url":"git://github.com/hoene/omnitone.git","ssh_url":"git@github.com:hoene/omnitone.git","clone_url":"https://github.com/hoene/omnitone.git","svn_url":"https://github.com/hoene/omnitone","homepage":"https://googlechrome.github.io/omnitone","size":255773,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"GoogleChrome:master","ref":"master","sha":"57281bc5ad1fef49147811d546e8bb519c445824","user":{"login":"GoogleChrome","id":1778935,"avatar_url":"https://avatars.githubusercontent.com/u/1778935?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleChrome","html_url":"https://github.com/GoogleChrome","followers_url":"https://api.github.com/users/GoogleChrome/followers","following_url":"https://api.github.com/users/GoogleChrome/following{/other_user}","gists_url":"https://api.github.com/users/GoogleChrome/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleChrome/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleChrome/subscriptions","organizations_url":"https://api.github.com/users/GoogleChrome/orgs","repos_url":"https://api.github.com/users/GoogleChrome/repos","events_url":"https://api.github.com/users/GoogleChrome/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleChrome/received_events","type":"Organization","site_admin":false},"repo":{"id":60283346,"name":"omnitone","full_name":"GoogleChrome/omnitone","owner":{"login":"GoogleChrome","id":1778935,"avatar_url":"https://avatars.githubusercontent.com/u/1778935?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleChrome","html_url":"https://github.com/GoogleChrome","followers_url":"https://api.github.com/users/GoogleChrome/followers","following_url":"https://api.github.com/users/GoogleChrome/following{/other_user}","gists_url":"https://api.github.com/users/GoogleChrome/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleChrome/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleChrome/subscriptions","organizations_url":"https://api.github.com/users/GoogleChrome/orgs","repos_url":"https://api.github.com/users/GoogleChrome/repos","events_url":"https://api.github.com/users/GoogleChrome/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleChrome/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/GoogleChrome/omnitone","description":"Spatial Audio on the Web.","fork":false,"url":"https://api.github.com/repos/GoogleChrome/omnitone","forks_url":"https://api.github.com/repos/GoogleChrome/omnitone/forks","keys_url":"https://api.github.com/repos/GoogleChrome/omnitone/keys{/key_id}","collaborators_url":"https://api.github.com/repos/GoogleChrome/omnitone/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/GoogleChrome/omnitone/teams","hooks_url":"https://api.github.com/repos/GoogleChrome/omnitone/hooks","issue_events_url":"https://api.github.com/repos/GoogleChrome/omnitone/issues/events{/number}","events_url":"https://api.github.com/repos/GoogleChrome/omnitone/events","assignees_url":"https://api.github.com/repos/GoogleChrome/omnitone/assignees{/user}","branches_url":"https://api.github.com/repos/GoogleChrome/omnitone/branches{/branch}","tags_url":"https://api.github.com/repos/GoogleChrome/omnitone/tags","blobs_url":"https://api.github.com/repos/GoogleChrome/omnitone/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/GoogleChrome/omnitone/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/GoogleChrome/omnitone/git/refs{/sha}","trees_url":"https://api.github.com/repos/GoogleChrome/omnitone/git/trees{/sha}","statuses_url":"https://api.github.com/repos/GoogleChrome/omnitone/statuses/{sha}","languages_url":"https://api.github.com/repos/GoogleChrome/omnitone/languages","stargazers_url":"https://api.github.com/repos/GoogleChrome/omnitone/stargazers","contributors_url":"https://api.github.com/repos/GoogleChrome/omnitone/contributors","subscribers_url":"https://api.github.com/repos/GoogleChrome/omnitone/subscribers","subscription_url":"https://api.github.com/repos/GoogleChrome/omnitone/subscription","commits_url":"https://api.github.com/repos/GoogleChrome/omnitone/commits{/sha}","git_commits_url":"https://api.github.com/repos/GoogleChrome/omnitone/git/commits{/sha}","comments_url":"https://api.github.com/repos/GoogleChrome/omnitone/comments{/number}","issue_comment_url":"https://api.github.com/repos/GoogleChrome/omnitone/issues/comments{/number}","contents_url":"https://api.github.com/repos/GoogleChrome/omnitone/contents/{+path}","compare_url":"https://api.github.com/repos/GoogleChrome/omnitone/compare/{base}...{head}","merges_url":"https://api.github.com/repos/GoogleChrome/omnitone/merges","archive_url":"https://api.github.com/repos/GoogleChrome/omnitone/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/GoogleChrome/omnitone/downloads","issues_url":"https://api.github.com/repos/GoogleChrome/omnitone/issues{/number}","pulls_url":"https://api.github.com/repos/GoogleChrome/omnitone/pulls{/number}","milestones_url":"https://api.github.com/repos/GoogleChrome/omnitone/milestones{/number}","notifications_url":"https://api.github.com/repos/GoogleChrome/omnitone/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/GoogleChrome/omnitone/labels{/name}","releases_url":"https://api.github.com/repos/GoogleChrome/omnitone/releases{/id}","deployments_url":"https://api.github.com/repos/GoogleChrome/omnitone/deployments","created_at":"2016-06-02T17:21:26Z","updated_at":"2017-02-23T22:34:11Z","pushed_at":"2017-02-24T16:25:41Z","git_url":"git://github.com/GoogleChrome/omnitone.git","ssh_url":"git@github.com:GoogleChrome/omnitone.git","clone_url":"https://github.com/GoogleChrome/omnitone.git","svn_url":"https://github.com/GoogleChrome/omnitone","homepage":"https://googlechrome.github.io/omnitone","size":255771,"stargazers_count":306,"watchers_count":306,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":41,"mirror_url":null,"open_issues_count":9,"forks":41,"open_issues":9,"watchers":306,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/GoogleChrome/omnitone/pulls/33"},"html":{"href":"https://github.com/GoogleChrome/omnitone/pull/33"},"issue":{"href":"https://api.github.com/repos/GoogleChrome/omnitone/issues/33"},"comments":{"href":"https://api.github.com/repos/GoogleChrome/omnitone/issues/33/comments"},"review_comments":{"href":"https://api.github.com/repos/GoogleChrome/omnitone/pulls/33/comments"},"review_comment":{"href":"https://api.github.com/repos/GoogleChrome/omnitone/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/GoogleChrome/omnitone/pulls/33/commits"},"statuses":{"href":"https://api.github.com/repos/GoogleChrome/omnitone/statuses/fc2adb22c81b89be140cba52ac7e7b79a5d128ef"}}}}
{"actor":{"display_login":"hoch"}}