Applying a filter to AudioContext - javascript

I'm attempting to apply a low-pass filter to a sound I load and play through SoundJS.
Right now I'm attempting to do this like this:
var audio = createjs.Sound.activePlugin;
var source = audio.context.createBufferSource();
// Create the filter
var filter = audio.context.createBiquadFilter();
// Create the audio graph.
source.connect(filter);
filter.connect(audio.context.destination);
// Create and specify parameters for the low-pass filter.
filter.type = 0; // Low-pass filter. See BiquadFilterNode docs
filter.frequency.value = 440; // Set cutoff to 440 HZ
// Playback the sound.
createjs.Sound.play("Song");
But I'm not having much luck. Could someone point me in the right direction?
Thanks

When I built the MusicVisualizer demo one of the interesting limitations I found was that all of the audio nodes had to be built using the same context to work. You can access the SoundJS context via createjs.WebAudioPlugin.context
You'll also need to connect your filter into the existing node flow if you want it to work as expected. You can see the MusicVisualizer demo on github if you want to review the source, which does this. You can also review the documentation online, which might be helpful.
Hope that helps.

Related

Sankey-diagram PowerBI custom visual with color nodes and ordering

The sankey diagram of PowerBI has many possibilities but as you can read on the github site there are some important limitations. The first is that it is not possible to color the nodes. In addition, it is also not possible to change the order of the nodes (both source and destination).
Attached is an example PowerBI file in which a sankey is displayed. In this file is indicated which colors the nodes should have and what the order of the nodes should be.
The best solution is of course to use PowerBI to indicate the colors as in this example with the links. But probably it is easier to indicate the colors of the nodes (names) in the code itself with a hard value this would also be a nice alternative. Same holds for the ordering of the nodes
I looked at the colorscale function of d3 to link it to fillcolor. But I got an error message that the string values cannot be linked to colorscale.
The Github page with the code can be found here:
https://github.com/microsoft/powerbi-visuals-sankey
I think this line of code should change:
nodeFillColor = this.colorHelper.isHighContrast ? this.colorHelper.getThemeColor() : this.colorPalette.getColor(index.toString()).value;
console.log(nodeFillColor);
nodeStrokeColor = this.colorHelper.getHighContrastColor("foreground", nodeFillColor);
The colors are now based on a theme color. Hopefully it is possible to link the nodes (name) to a color instead of a theme.
Hopefully you can help me and other users of the Sankey.
It looks like if you need to inject some 3rd party color values (whether hex or some other format) you can use the ColorHelper instance at play in the code you highlighted to "cheat". The following example can be found in the powerbi documentation here: https://github.com/microsoft/powerbi-visuals-utils-colorutils/blob/master/docs/api/colorUtils.md#calculatehighlightcolor
import ColorUtility = powerbi.extensibility.utils.color;
let yellow = "#FFFF00",
yellowRGB = ColorUtility.parseColorString(yellow);
ColorUtility.calculateHighlightColor(yellowRGB, 0.8, 0.2);
// returns: '#CCCC00'
Ultimately I think it comes down to this one helper method:
ColorUtility.parseColorString('<colorhex>')
I don't know exactly the best way to plug it in to what you're doing, but you might try generating a random hex color and plugging it in to see what comes out the other side.
// thanks Paul Irish: https://www.paulirish.com/2009/random-hex-color-code-snippets/
let randcolor = '#'+Math.floor(Math.random()*16777215).toString(16)
// Then to replace the example code you had in your question...
nodeFillColor = this.colorHelper.parseColorString(randcolor)
nodeStrokeColor = this.colorHelper.getHighContrastColor("foreground", nodeFillColor);

Trying to filter sentinel 2 images by percent cloud cover

I am trying to filter Sentinel 2 images by percent of cloud cover (say, 20%) and then perform some image arithmetic on the output.
I am trying to do implement what is found here:gis.stackexchange thread (https://gis.stackexchange.com/questions/303344/filter-landsat-images-cloud-cover). Unfortunately, the function ee.Algorithms.Landsat... does not work with Sentinel 2 images, which is required for what I am doing.
My code thus far is below.
var myCollection = ee.ImageCollection('COPERNICUS/S2');
var dataset2 = ee.ImageCollection(
myCollection.filterBounds(point) //use only one image that contains the POI
.filterDate('2015-06-23', '2019-04-25') //filter by date range
);
var ds2_cloudiness = dataset2.map(function(image){
var cloud = ee.Algorithms.Landsat.simpleCloudScore(image).select('cloud');
var cloudiness = cloud.reduceRegion({
reducer: 'median'
});
return image.set(cloudiness);
});
var filteredCollection = ds2_cloudiness.filter(ee.Filter.lt('cloud', 20));
Map.addLayer(filteredCollection, {min: -.2, max:.2}, 'test')
This outputs an error: Landsat.simpleCloudScore: Image is not a Landsat scene or is missing SENSOR_ID metadata. Any nudge in the right direction would be appreciated.
I think there is a simpler approach if you just want to filter using cloud cover percentage. You can do this by filtering based on the image metadata.
var myCollection = ee.ImageCollection('COPERNICUS/S2');
print(myCollection.first())
If you inspect the first image in the Sentinel-2 imageCollection you can actually see its metadata (only for that image). Since, you are working with a homogeneous and well maintained image collection, you can expect the other images to have similar porperties. From here, you can do the following
myCollection = myCollection.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE',20));
print(myCollection.first());
This particular code will filter the image collection to find images with cloud cover less than or equal to 20. You can verify this by either once again checking the first image or checking the size of the collection which should have narrowed.
However, if you are looking for a separate algorithm to calculate cloud over an image, you'll probably have to write one for Sentinel (yet).

Avoid cleaning canvas in updateOptions call

I am working in a signals plot program trying to simulate the 'persistence' feature as available in many oscilloscopes.
I would like to prevent dygraph canvas to clean for every updateOptions call. Instead of that, my plot should be preserved until an explicit call for cleaning. This feature will allow me to check if a signal preserves its phase during a certain amount of time.
I tried to use block_redraw parameter set to false in updateOptions function without no success.
Any ideas?
This isn't really something dygraphs is designed to do. You're asking it to render the full history of its data source, rather than the current state of its data source.
That being said, here's the code that clears the plotting canvas:
DygraphCanvasRenderer.prototype.clear = function() {
this.elementContext.clearRect(0, 0, this.width, this.height);
};
So if you override that, it might do what you want:
DygraphCanvasRenderer.prototype.clear = function() {};
That being said, this is liable to break lots of things (like zooming and panning) in addition to giving you the behavior you want. You can see this if you visit the live random data demo page and copy that snippet into the JS console.
Good luck!

Web Audio API - Removing filter

I'm building a visualiser with multiple graphic modes. For a few of them I need to calculate the beat of the track being played, and as I understand I then need to apply a lowpass filter like the following, to enhance frequencies that are most probable to hold drum sounds:
var filter = context.createBiquadFilter();
source.connect(filter);
filter.connect(context.destination);
filter.type = 'lowpass';
But what if I want to turn the filter off? Do I have to re-connect the source every time I need to remove the filter? Would this have any negative effect on performance?
Related question: how much performance loss would I experience if I have two two sources, from the same audio source, and apply the filter to one of them?
how much performance loss would I experience if I have two two sources, from the same audio source, and apply the filter to one of them
You can connect a single audio node to multiple destinations, thus you never need a duplicate source just to spread-connect it. If you need filtered and raw audio simultaneously, you can just setup your connections accordingly:
var filter = context.createBiquadFilter();
source.connect(filter);
source.connect(context.destination);
filter.connect(context.destination);
filter.type = "lowpass";
Anyways, setting the type property of a FilterNode to "allpass" will effectively disable all filtering, without having to reconnect:
filter.type = "allpass"
According to article WebAudio intro | html5rocks, I would have to toggle the filter on and off, by disconnecting the source and itself like so:
this.source.disconnect(0);
this.filter.disconnect(0);
// Check if we want to enable the filter.
if (filterShouldBeEnabled) {
// Connect through the filter.
this.source.connect(this.filter);
this.filter.connect(context.destination);
} else {
// Otherwise, connect directly.
this.source.connect(context.destination);
}

Easljs Applying filters to bitmap

I'm trying to figure out how to add filters ti a video source with easljs. According to the documentation, I can just set filters to the bitmap.filtes property. This doesn't seem to work though. There is no error or anything, the filters are just not applied at all.
One confusion about the documentation, is that it mentions that cache() must be called on the display object in order for filters to be applied but for the bitmap class, it says that cache() should not be called.
Below is the code that I'm using as a test:
var stage = new createjs.Stage('screen');
var video = document.getElementById('source');
var bitmap = new createjs.Bitmap(video);
bitmap.scaleX = 0.44;
bitmap.scaleY = 0.44;
bitmap.y = 30;
bitmap.filters = [
new createjs.ColorFilter(0,0,0,1,255,0,0),
new createjs.BoxBlurFilter(5, 5, 10)
];
stage.addChild(bitmap);
The documentation regarding Bitmap and Filters is misleading - and I will make sure it is updated for the next release.
Caching of a bitmap should be avoided because it will NOT provide any performance benefit, which you will get from caching containers, shapes, and Text. In fact, it can even degrade performance instead because it will use additional memory to store the cached version
But you MUST cache a bitmap to apply filters to it. Add a cache call to your sample, and it should work.
Sorry for any confusion that is caused by the documentation.

Categories

Resources