Code Monkey home page Code Monkey logo

googlechrome / audion Goto Github PK

View Code? Open in Web Editor NEW
357.0 22.0 55.0 5.52 MB

Audion is a Chrome extension that adds a Web Audio panel to Developer Tools. This panel visualizes the web audio graph in real-time.

Home Page: https://chrome.google.com/webstore/detail/web-audio-inspector/cmhomipkklckpomafalojobppmmidlgl

License: Apache License 2.0

JavaScript 27.24% HTML 6.14% CSS 0.49% Shell 0.02% Mustache 0.12% TypeScript 65.99%
web-audio chrome-extension developer-tools

audion's Introduction

Audion: Web Audio Graph Visualizer

Node.js CI

Audion is a Chrome extension that adds a panel to DevTools. This panel visualizes the audio graph (programmed with Web Audio API) in real-time. Soon you will be able to install the extension from Chrome Web Store page.

Google Doodle Hiphop

Usage

  1. Install the extension from Chrome Web Store.
    1. Alternatively, you can clone this repository and build the extension locally. Follow this instruction to load the local build.
  2. Open Chrome Developer Tools. You should be able to find “Web Audio” panel in the top. Select the panel.
  3. Visit or reload a page that uses Web Audio API. If the page is loaded before opening Developer Tools, you need to reload the page for the extension to work correctly.
  4. You can pan and zoom with the mouse and wheel. Click the “autofit” button to fit the graph within the panel.

Development

Build and test the extension

  1. Install NodeJS 14 or later.
  2. Install dependencies with npm ci or npm install.
  3. Run npm test to build and test the extension.

Install the development copy of the extension

  1. Open chrome://extensions in Chrome.
  2. Turn on Developer mode if it is not already active.
  3. Load an unpacked extension with the Load unpacked button. In the file modal that opens, select the audion directory inside of the build directory under the copy of this repository.

Use and make changes to the extension

  1. Open the added Web Audio panel in an inspector window with a page that uses Web Audio API.
  2. Make changes to the extension and rebuild with npm test or npm run build.
  3. Open chrome://extensions, click Update to reload the rebuilt extension. Close and reopen any tab and inspector to get the rebuilt extension's panel.

Use extra debugging information

  1. Open the extension option panel and check "Click here to show more debug info".
  2. Right click the visualizer panel and click "Inspect" to the extension's DevTools panel, and see the console for the extra debugging information.

Acknowledgments

Special thanks to Chi Zeng (Google), Gaoping Huang, Michael "Z" Goddard (Bocoup) and Tenghui Zhang for their contribution on this project.

Contribution

If you have found an error in this library, please file an issue at: https://github.com/GoogleChrome/audion/issues.

Patches are encouraged, and may be submitted by forking this project and submitting a pull request through GitHub. See CONTRIBUTING for more detail.

License

Copyright 2021 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

audion's People

Contributors

dependabot[bot] avatar hoch avatar max-vogler avatar mzgoddard avatar patrickkettner avatar scheib avatar tenghuizhang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

audion's Issues

npm Install failure: EACCES on ~/.npm/duplexify/3.5.0

I don't understand why npm install needs sudo here.

npm WARN deprecated [email protected]: use uuid module instead
npm ERR! Darwin 16.4.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install"
npm ERR! node v6.9.0
npm ERR! npm  v3.10.8
npm ERR! path /Users/$USER/.npm/duplexify/3.5.0
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall mkdir

npm ERR! Error: EACCES: permission denied, mkdir '/Users/$USER/.npm/duplexify/3.5.0'
npm ERR!     at Error (native)
npm ERR!  { Error: EACCES: permission denied, mkdir '/Users/$USER/.npm/duplexify/3.5.0'
npm ERR!     at Error (native)
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'mkdir',
npm ERR!   path: '/Users/$USER/.npm/duplexify/3.5.0',
npm ERR!   parent: 'vinyl-fs' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.

Note: I am running macOS Sierra 10.12.3 (16D32). $USER is my home directory.

Enhancement: add a label to nodes in the graph

With big graphs it could be useful to be able to click on some nodes in the graphic view of the graph, and add labels. LocalStorage could be use to save/load the mapping.
Or maybe color (or add a border color) the nodes belonging to some "logical modules in the webaudio app".

Should we allow for varying AudioParam values?

I think it's a tradeoff. I'm leaning towards showing realtime values, but not letting the user vary them.

Varying AudioParam's is neat - it can be useful to experiment / tinker, but the feature implies maintaining a reference to nodes, preventing GC. Blocking a source node from getting GCed could prevent its entire AudioBuffer from getting GCed ... which might be bad?

If we just let the user view AudioParam values in realtime, we might not need to maintain references to the nodes. We would just I think override the getters and setters of the value properties to issue a message when values change, maybe by defining a proxy.

Allow modifying AudioParam values.

A challenge here is that it seems like we have to maintain a reference to tracked nodes in the inspected page. That might prevent garbage collection ...

Workflow improvement

Why do we need Node and Gulp when Closure does all the heavy lifting? Perhaps we can just use the shell script to run the compiler?

Let users delete edges in the UI.

Today, users can delete edges by nabbing a reference to the node via the __node__ method and then disconnecting.

var node = __node__([NUMERIC NODE ID]);
node.disconnect();

It might be nice to enable deleting nodes in the UI itself. The extension would pass a message from the dev tools panel to the content script of the web page telling the web page to remove the disconnect the node.

This task involves

  1. Making the edges interactive via JointJS's API. This introduces an X button atop each edge when the user hovers over it.
  2. Introducing a new type of message AudionRequestNodeDisconnectMessage to externs/audion-specific-externs/messages-extern.js.
  3. Sending a message from the panel to the dev tools script when the user clicks X.
  4. Routing that message from the dev tools script to the background script to the content script of the web page.
  5. Actually disconnecting the node in tracing.js (the code that runs in the context of the web page).

Occasional build error related to the CSS name mapping.

Occasionally, building the extension errs because the CSS name mapping cannot be found by Closure.

chizeng-macbookpro:audion chizeng$ gulp
[23:55:06] Using gulpfile ~/Desktop/audion/gulpfile.js
[23:55:06] Starting 'default'...
[23:55:06] Finished 'default' after 26 ms
Full name optimization profit : 251
Word-by-word optimization profit : 249
Recommended method : 'full'
events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: ENOENT: no such file or directory, lstat '/tmp/audion-build-temporary-files/rename-mapping.js'

Re-running would often suffice, but this behavior is random and unexpected, so it ought to be fixed.

Remove dagre-d3.

Remove dagre-d3 and its extern from this code base. Keep graphlib + dagre (Install those via npm).

Tidy up the warning message

  • Create a wrapping container for the panel.
  • The warning message should be centered vertically and horizontally.
  • Give some edges on the style. :)

Flesh out how letting the user set params would work.

Overriding AudioParam values is useful. We should I think work out details. For instance,

  • If the inspected page tries to override a user-set value, which value should audion heed?
  • If the user sets a value during a ramp, what happens?
  • Similarly, what if the user sets a value when an oscillator connects to the AudioParam?

ES6 classes that inherits from AudioNode stopped working when the extension is enabled

Hi, this example: https://codepen.io/w3devcampus/pen/GWGdjK?editors=0010
A frequency analyser I wrote, that uses an ES6 class that inherit from the AnalyserNode, stops working when the extension is activated. If I disable the extension it works (works also with FF, opera etc.)

It seems that the fact that the class inherits from a WebAudio node confuses the extension/browser, and raises erros when I try to call internal methods from the code in the class.

Add Closure-based testing for the graph.

Ideally, our tests should run on say jenkins with a web hook for GitHub. However, I don't know if Closure jives with jenkins. I haven't seen solid examples.

What we can do is set up Closure-based testing. The user would run a terminal command and then visit a web page to run tests.

One meaningful test would be to ensure that the correct graph is created when a certain sequence of events is passed to the panel script. We would include the panel script in the test and mock onMessage so that the test could manually pass messages to the panel.

I marked this as a post-launch priority because there are some significant challenges we have to figure out about Closure in GitHub, but tests would later enable others to contribute more easily.

Track when AudioBufferSourceNodes start and stop playing.

We should show when AudioBufferSourceNodes start and stop playing in the pane:

audiobuffersourcenode

Maybe we could add a Play Status section to the pane for AudioBufferSourceNodes. This section could have 3 properties, perhaps start time (the absolute time at which the node starts playing), offset (at what point - seconds - into the buffer we start playing), and duration (how long in seconds the node played for).

This bug entails

  1. overriding the AudioBufferSourceNode.prototype.start method to issue a message when the node starts playing.
    https://github.com/google/audion/blob/master/js/entry-points/tracing.js
    The message's properties should be added to messages-extern.js:
    https://github.com/google/audion/blob/master/externs/audion-specific-externs/messages-extern.js
    The message's type should be added to this enumeration:
    https://github.com/google/audion/blob/master/js/messaging/message-type.js

  2. Within tracing.js, listen for AudioBufferSourceNodes to dispatch an ended event to handle when the node stops playing: https://www.w3.org/TR/webaudio/#widl-AudioBufferSourceNode-onended

  3. adding a new category of widgets in the pane (a section in the pane) for Play Status:
    https://github.com/google/audion/blob/795545d1692d11a0348556827622c997dbc9502e/js/ui/pane/audio-node-mode.js#L91
    that only appears if the node is an AudioBufferSourceNode.

Create a right hand pane.

Create a pane on the right that expands and contracts. This sets the stage for letting users vary audio params with sliders.

gulp-closure-compiler needs JDK on macOS

Since macOS does not have JDK out of the box, gulp-closure-compiler fails when it runs java command line tool. Certainly you can just install it, but this needs to be documented in the prerequisite section.

Extension breaks otherwise working site

I'm working on a beat production app. You can see it in progress here:
http://bb.upchicago.org
I was really excited to try this chrome extension, but as you can see if you visit the site with the extension installed, you get a node connecting error of some sort:
Uncaught Error: error connecting to node: [object DynamicsCompressorNode]

Uninstall the extension and the site immediately works again.
Any ideas? Happy to change my code to make this work, just not sure where to begin.
Thanks!

Let users screenshot graphs via the extension.

It seems like a use case for Web Audio Inspector is obtaining an image of the graph. Users today generally use native screenshot tools (depending on the OS).

It would be nice if the user could screenshot through the extension. There could be a button for it in the dev tools panel.

A first step would be to find out at what layer to do this. JointJS is SVG-based - maybe we can let the user download that SVG image. Or maybe Chrome has an extension API for screenshotting dev tools.

BaseAudioContext.createSpatialPanner should not be defined.

BaseAudioContext.prototype includes createSpatialPanner. This is incorrect; there is no such property defined for BaseAudioContext.

Wrapping of properties should be more careful and only create wrappers for properties that actually exist in a BaseAudioContext.

Remove the synchronous XMLHttpRequest.

I used a synchronous XHR request in 8bbce3b to solve #13, but regret since it causes a console warning.

Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.

I personally like a clean console. :) It might mean embedding tracing.js another way. Maybe as a string.

Event tracking (and logging)

Here is the list of events that might be interesting to track, possibly with HighResDomTimestamp:

  • ContextCreated (contextID)
  • ContextSuspended (contextID)
  • ContextResumed (contextID)
  • ContextClosed (contextID)
  • NodeCreated (nodeID)
  • NodeToNodeConnected (nodeID_a, nodeID_b)
  • NodeToParamConnected (nodeID_a, nodeID_b, paramName)
  • NodeFromNodeDisconnected (nodeID_a, optional nodeID_b)
  • NodeFromParamDisconnected (nodeID_a, nodeID_b, paramName)
  • ParamAutomationStarted (nodeID, paramName, automationType)
  • SourceStarted (nodeID)
  • SourceStopped (nodeID)
  • TypeChanged (nodeID, newTypeValue)

I believe every operation in the graph should be accountable with one of events above.

Let the background page track tabs that missed web audio updates.

If a content script (for a frame) sends a web audio update to the background script, and no dev panel is open for that tab, then the background script should track the IDs of tabs that missed web audio updates. That way, the dev panel can notify the user that some updates had been missed (and the user might want to refresh).

Make unit tests more nuanced.

Today, our unit test is a large, monolithic test that

  1. constructs a graph by passing messages to the panel script and
  2. performs a massive object comparison:

https://github.com/google/audion/blob/master/tests/panel_test.js
This takes the unit out of unit testing. :(

Instead of doing a massive object property comparison, the test should assert for specific details such as the existence of various nodes as well as the specific connections.

Relatedly, we need to test more cases as noted in the TODO within that file. Making the test more concise is a first step that would enable that.

Writing tests is grungy, but important: As we develop more features, we must ensure that we preserve old behavior. I will contribute to this bug and expand test coverage - and anybody else is encouraged to as well.

The Web Audio panel only starts tracking audio graph after user clicks on the 'Web Audio' tab.

Currently, only opening Chrome dev tools is not enough to trigger the panel to track the audio graph. The user has to actually click on the 'Web Audio' tab. This is bad because the user might expect web audio calls to start being tracked as soon as they open the dev panel in general, and only the panel JS owns tracking the audio graph.

The problem stems from how Chrome dev tools only creates panel.html when the user clicks the tab. dev-tools.js runs

One way we can solve this is queue audio graph updates til the Web Audio panel opens, then send them all at once.

Or we can just force the user to activate the panel when the user opens dev tools then clicks the Web Audio tab for the first time after opening dev tools.

Or we can make it clear to the user that navigating to the Web Audio tab finally starts tracking web audio calls.

Design visualizations of audio.

It may be useful to visualize audio entering the numeric input channel of each AudioNode. First, we should research and justify what type of visualization(s) would be most useful - a waveform/oscilloscope? A histogram of the frequency domain?

For starters, a user may want to know whether any audio is going into an input at all. Beyond that, I wonder what information is most useful to visualize.

After making that design call, we use native AnalyserNodes to collect the data needed for visualization. That logic will reside in js/entry-points/tracing.js.

Audio graph constrained when starting out small.

If an audio graph starts out small / narrow, it gets perpetually constrained into this rectangle despite later zooming.

constrainedgraph

Lets just make the svg container of the graph be as tall and wide as possible (fill the dev page).

Consider disabling and enabling tracking web audio from within the web audio panel.

Occasionally, a user may want to disable web audio tracking. For instance, the user may be benchmarking performance - this extension's web audio tracking logic adds unwanted overhead.

Today, the user disables the extension by visiting chrome://extension. The user could alternatively uninstall the extension from its icon to the right of Chrome's URL bar.

It would be nice if the extension itself could allow for disabling or enabling web audio tracking, perhaps via buttons within the Web Audio panel in dev tools. Then, the extension could always be "enabled" by the user, which probably leads to to fewer uninstallations. Furthermore, disabling / enabling web audio tracking within the Web Audio panel seems like a smoother flow than the aforementioned alternatives.

Audion breaks Box2DJS demo

With Audion enabled, navigate to the Box-2D demo. The demo fails with the following console message:

prototype-1.6.0.2.js:209 Uncaught TypeError: Failed to construct 'AudioContext': Please use the 'new' operator, this DOM object constructor cannot be called as a function.
    at new <anonymous> (prototype-1.6.0.2.js:209)
    at T (<anonymous>:4:23)
    at new AudioContext (<anonymous>:24:19)
    at init (box2d-audio.html:190)
    at wrapper (prototype-1.6.0.2.js:3877)
(anonymous)	@	prototype-1.6.0.2.js:209
T	@	VM11451:4
AudioContext	@	VM11451:24
init	@	box2d-audio.html:190
wrapper	@	prototype-1.6.0.2.js:3877

Can "connection" be selectable?

This feature was in the original Canopy visualizer. It is often useful to inspect the source and the destination of a connection.

Allow AudioNodes to be GCed when DevTools is closed.

The extension maintains a mapping between node ID (a unique value assigned to each AudioNode) and AudioNode for each web page.
https://github.com/google/audion/blob/795545d1692d11a0348556827622c997dbc9502e/js/entry-points/tracing.js#L108

This means that AudioNodes are never garbage-collected, but we do allow the user to obtain a reference to any AudioNode via the __node__ function. However, when Developer Tools is closed, there should be no reason for the extension to maintain references to AudioNodes.

Today, when the extension's background script receives a web audio update from a tab, it tries to find a connection to a dev tools instance (and such a connection only exists if dev tools is open for that tab):
https://github.com/google/audion/blob/795545d1692d11a0348556827622c997dbc9502e/js/entry-points/background.js#L119

We should add an else block to that logic: If dev tools is closed, we send a MISSING_AUDIO_UPDATES message ...
https://github.com/google/audion/blob/795545d1692d11a0348556827622c997dbc9502e/js/entry-points/background.js#L192

back to the content script of the tab telling the page to drop all references. This message is routed through the content script to code injected within the page itself.
https://github.com/google/audion/blob/795545d1692d11a0348556827622c997dbc9502e/js/entry-points/inject-tracing.js#L30

The injected logic would then handle that message appropriately.
https://github.com/google/audion/blob/795545d1692d11a0348556827622c997dbc9502e/js/entry-points/tracing.js#L1184

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.