Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor to put all canvas-related functions in one Renderer class
Browse files Browse the repository at this point in the history
also enables customization of the `osc` method
yuwash committed Dec 25, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent dac2580 commit 28423ea
Showing 4 changed files with 69 additions and 61 deletions.
35 changes: 19 additions & 16 deletions example/app.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import {MediaStreamOscilloscope, getUserMedia} from "../dist/index";
import {Renderer} from "../tools/canvas_tools";

let stats = document.querySelector(".status");
let cvs = cvs = document.querySelector(".cvs");
let cvs = document.querySelector(".cvs");

function fancyGraph(ctx,width,height){
let backstrokeStyle = ctx.strokeStyle;
ctx.strokeStyle = "#444";
ctx.fillRect(0,0,width,height);
ctx.beginPath();
for(let i=0; i<width; i+=10){
ctx.moveTo(i,0);
ctx.lineTo(i,height);
class FancyGraphRenderer extends Renderer{
primer(){
this.cctx.strokeStyle = "#444";
this.cctx.fillRect(0,0,this.width,this.height);
this.cctx.beginPath();
for(let i=0; i<this.width; i+=10){
this.cctx.moveTo(i,0);
this.cctx.lineTo(i,this.height);
}
for(let j=0; j<this.height; j+=10){
this.cctx.moveTo(0,j);
this.cctx.lineTo(this.width,j);
}
this.cctx.stroke();
this.cctx.strokeStyle = this.strokeStyle;
}
for(let j=0; j<height; j+=10){
ctx.moveTo(0,j);
ctx.lineTo(width,j);
}
ctx.stroke();
ctx.strokeStyle = backstrokeStyle;
}
function startOsc(){
renderer = new FancyGraphRenderer(cvs);
getUserMedia({audio: true})
.then(stream=>{
if(!stream) {
@@ -31,7 +34,7 @@ function startOsc(){
stats.classList.add("success");
stats.classList.remove("error");
stats.innerHTML = "Listening to your microphone, Try saying something";
let osc = new MediaStreamOscilloscope(stream, cvs, null, 2048, null, fancyGraph);
let osc = new MediaStreamOscilloscope(stream, renderer, null, 2048);
osc.start();
document.querySelector(".btn.pause").addEventListener("click",()=>{
stats.innerHTML = "Oscilloscope Paused";
30 changes: 12 additions & 18 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
"use strict";
import * as _ct from "./tools/canvas_tools";
function Oscilloscope(audioContext, audioSource, canvasElement, audioDest = null, analyzerFFT = 2048, canvasInitFunction = null, drawingPrimerFunction = null){

function Oscilloscope(audioContext, audioSource, renderer, audioDest = null, analyzerFFT = 2048){
this.actx = audioContext;
this.FFT = analyzerFFT;
this.cvs = canvasElement;
this.init = canvasInitFunction || _ct._initCvs;
this.primer = drawingPrimerFunction || _ct._primer;
this.renderer = renderer;
this.paused = false;
this.anl = this.actx.createAnalyser();
this.ctx = audioContext;
@@ -16,18 +14,14 @@ function Oscilloscope(audioContext, audioSource, canvasElement, audioDest = null
this.src.connect(this.anl);
if(this.dest) this.anl.connect(this.dest);
// Set up Canvas
let {width = 300, height = 150} = this.cvs;
this.WIDTH = width;
this.HEIGHT = height;
this.u8ar = new Uint8Array(this.FFT);
this.cctx = this.cvs.getContext("2d");
this.init(this.cctx,this.WIDTH,this.HEIGHT);
this.renderer.init();
this.draw = () =>{
if(!this.paused) requestAnimationFrame(this.draw);
this.cctx.clearRect(0 , 0, this.WIDTH, this.HEIGHT);
this.primer(this.cctx, this.WIDTH, this.HEIGHT);
this.renderer.reset();
this.renderer.primer();
this.anl.getByteTimeDomainData(this.u8ar);
_ct._drawRawOsc(this.cctx, this.u8ar, this.WIDTH, this.HEIGHT);
this.renderer.osc(this.u8ar);
}
this.start = () => {
this.paused = false;
@@ -40,9 +34,9 @@ function Oscilloscope(audioContext, audioSource, canvasElement, audioDest = null
this.paused = true;
requestAnimationFrame(()=>{
this.u8ar = new Uint8Array(this.FFT).fill(0);
this.cctx.clearRect(0 , 0, this.WIDTH, this.HEIGHT);
this.primer(this.cctx, this.WIDTH, this.HEIGHT);
_ct._drawRawOsc(this.cctx, this.u8ar, this.WIDTH, this.HEIGHT);
this.renderer.reset();
this.renderer.primer();
this.renderer.osc(this.u8ar);
});
}
}
@@ -51,10 +45,10 @@ function createAudioContext(){
return new (window.AudioContext || window.webkitAudioContext)();
}

function MediaStreamOscilloscope(mediaStream, canvasElement, audioDest = null, analyzerFFT = 2048, canvasInitFunction = null, drawingPrimerFunction = null){
function MediaStreamOscilloscope(mediaStream, renderer, audioDest = null, analyzerFFT = 2048){
let ctx = createAudioContext();
let src = ctx.createMediaStreamSource(mediaStream);
return new Oscilloscope(ctx, src, canvasElement, audioDest, analyzerFFT, canvasInitFunction, drawingPrimerFunction);
return new Oscilloscope(ctx, src, renderer, audioDest, analyzerFFT, renderer);
}

function getUserMedia(constraints){
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "webaudio-oscilloscope",
"version": "3.2.1",
"version": "4.0.0",
"keywords": [
"webaudio",
"oscilloscope",
63 changes: 37 additions & 26 deletions tools/canvas_tools.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,43 @@
const DEFAULT_FILL = "#111111";
const DEFAULT_STROKE = "#11ff11";
const HLINE_COLOR = "#555555";
function _initCvs(ctx, width, height){
ctx.fillStyle = DEFAULT_FILL;
ctx.strokeStyle = DEFAULT_STROKE;
}
function _primer(ctx, width, height){
ctx.fillRect(0,0,width,height);
ctx.strokeStyle = HLINE_COLOR;
ctx.beginPath();
ctx.moveTo(0, height / 2);
ctx.lineTo(width, height / 2);
ctx.stroke();
ctx.strokeStyle = DEFAULT_STROKE;
}
function _drawRawOsc(ctx,data,width,height){
ctx.beginPath();
for(let i=0; i < data.length; i++){
let x = i * (width * 1.0 / data.length); // need to fix x
let v = data[i] / 128.0;
let y = v * height / 2;
if(i === 0) ctx.moveTo(x,y);
else ctx.lineTo(x,y);
class Renderer{
fillStyle = DEFAULT_FILL
strokeStyle = DEFAULT_STROKE
hlineColor = HLINE_COLOR
constructor(canvasElement){
this.cvs = canvasElement;
let {width = 300, height = 150} = this.cvs;
this.width = width;
this.height = height;
this.cctx = this.cvs.getContext("2d");
}
init(){
}
primer(){
this.cctx.fillRect(0,0,this.width,this.height);
this.cctx.strokeStyle = this.hlineColor;
this.cctx.beginPath();
this.cctx.moveTo(0, this.height / 2);
this.cctx.lineTo(this.width, this.height / 2);
this.cctx.stroke();
this.cctx.strokeStyle = this.strokeStyle;
}
osc(data){
this.cctx.beginPath();
for(let i=0; i < data.length; i++){
let x = i * (this.width * 1.0 / data.length); // need to fix x
let v = data[i] / 128.0;
let y = v * this.height / 2;
if(i === 0) this.cctx.moveTo(x,y);
else this.cctx.lineTo(x,y);
}
this.cctx.stroke();
}
reset(){
this.cctx.clearRect(0 , 0, this.width, this.height);
}
ctx.stroke();
}
export {
_initCvs,
_primer,
_drawRawOsc
}
Renderer
}

0 comments on commit 28423ea

Please sign in to comment.