About

Reading CSS-Tricks i discovered the post of Matthew Ström on how to create a waveform which helped me create the library. Look for similar libraries to create custom waveforms. But almost all of them had the same type of wave and based on canvas and not on svg.

I think svg allows us a lot of customization with css filters or gradients or just lossless scaling. We can also store a path on the server and then retrieve it.

With the library we can create 2 types of waveforms linear and polar. I each method has 3 different types steps, mirror and bars.

Examples

All examples are made with this audio and processed in the browser.

Linear

View Options
{ 
    samples: 100, type: 'steps', top: 20,
    paths: [ 
        {d:'L', sx: 0, sy:0, ex:50, ey:100 },
        {d:'L', sx: 50, sy:100, ex:100, ey:0 }
    ]
}
View Options
{ 
    samples: 100, type: 'mirror', top: 20, 
    paths: [ 
        {d:'V', sy: 0, x:50, ey:100 }
    ]
}
View Options
{ 
    samples: 100,  type: 'steps', normalize: true, top: 20,
}
View Options
{ 
    samples: 100, type: 'mirror', top: 20,
    paths: [
        {d:'Q', sx: 20, sy:0, x: 50, y: 100, ex:80, ey:0}
    ],
}
View Options
{ 
    samples: 75, type: 'mirror', top: 20,
    paths: [
        //Five
        {d:'A', sx: 35, sy:85,  ex:65, ey:85, rx:10, ry: 10, angle: 180, arc: 1, sweep: 1, minshow: 0.8, maxshow: 1, normalize: true},  
        {d:'A', sx: 35, sy:85,  ex:65, ey:85, rx:10, ry: 10, angle: 180, arc: 1, sweep: 0, minshow: 0.8, maxshow: 1, normalize: true},

        {d:'A', sx: 30, sy:70,  ex:70, ey:70, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.8, maxshow: 1, normalize: true},
        {d:'A', sx: 30, sy:70,  ex:70, ey:70, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.8, maxshow: 1, normalize: true},

        {d:'A', sx: 25, sy:55,  ex:75, ey:55, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.8, maxshow: 1, normalize: true},
        {d:'A', sx: 25, sy:55,  ex:75, ey:55, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.8, maxshow: 1, normalize: true},

        {d:'A', sx: 20, sy:40,  ex:80, ey:40, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.8, maxshow: 1, normalize: true},
        {d:'A', sx: 20, sy:40,  ex:80, ey:40, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.8, maxshow: 1, normalize: true},

        {d:'A', sx: 15, sy:20,  ex:85, ey:20, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.8, maxshow: 1, normalize: true},
        {d:'A', sx: 15, sy:20,  ex:85, ey:20, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.8, maxshow: 1, normalize: true},

        {d:'A', sx: 10, sy:0,  ex:90, ey:0, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.8, maxshow: 1, normalize: true},
        {d:'A', sx: 10, sy:0,  ex:90, ey:0, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.8, maxshow: 1, normalize: true},

        //Four
        {d:'A', sx: 30, sy:70,  ex:70, ey:70, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.6, maxshow: 0.8, normalize: true },
        {d:'A', sx: 30, sy:70,  ex:70, ey:70, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.6, maxshow: 0.8, normalize: true },

        {d:'A', sx: 25, sy:55,  ex:75, ey:55, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.6, maxshow: 0.8, normalize: true },
        {d:'A', sx: 25, sy:55,  ex:75, ey:55, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.6, maxshow: 0.8, normalize: true },

        {d:'A', sx: 20, sy:40,  ex:80, ey:40, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.6, maxshow: 0.8, normalize: true },
        {d:'A', sx: 20, sy:40,  ex:80, ey:40, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.6, maxshow: 0.8, normalize: true },

        {d:'A', sx: 15, sy:20,  ex:85, ey:20, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.6, maxshow: 0.8, normalize: true },
        {d:'A', sx: 15, sy:20,  ex:85, ey:20, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.6, maxshow: 0.8, normalize: true },

        {d:'A', sx: 10, sy:0,  ex:90, ey:0, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.6, maxshow: 0.8, normalize: true },
        {d:'A', sx: 10, sy:0,  ex:90, ey:0, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.6, maxshow: 0.8, normalize: true },

        //Three
        {d:'A', sx: 20, sy:40,  ex:80, ey:40, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.4, maxshow: 0.6, normalize: true },
        {d:'A', sx: 20, sy:40,  ex:80, ey:40, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.4, maxshow: 0.6, normalize: true },

        {d:'A', sx: 15, sy:20,  ex:85, ey:20, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.4, maxshow: 0.6, normalize: true },
        {d:'A', sx: 15, sy:20,  ex:85, ey:20, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.4, maxshow: 0.6, normalize: true },

        {d:'A', sx: 10, sy:0,  ex:90, ey:0, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.4, maxshow: 0.6, normalize: true },
        {d:'A', sx: 10, sy:0,  ex:90, ey:0, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.4, maxshow: 0.6, normalize: true },

        //Two
        {d:'A', sx: 15, sy:20,  ex:85, ey:20, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.2, maxshow: 0.4, normalize: true },
        {d:'A', sx: 15, sy:20,  ex:85, ey:20, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.2, maxshow: 0.4, normalize: true },

        {d:'A', sx: 10, sy:0,  ex:90, ey:0, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0.2, maxshow: 0.4, normalize: true },
        {d:'A', sx: 10, sy:0,  ex:90, ey:0, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0.2, maxshow: 0.4, normalize: true },

        //One
        {d:'A', sx: 25, sy:0,  ex:75, ey:0, rx:20, ry: 20, angle: 180, arc: 1, sweep: 1, minshow: 0, maxshow: 0.2, normalize: true },
        {d:'A', sx: 25, sy:0,  ex:75, ey:0, rx:20, ry: 20, angle: 180, arc: 1, sweep: 0, minshow: 0, maxshow: 0.2, normalize: true },
        
    ],
}
View Options
{ 
    samples: 50,  type: 'steps',  top: 20,
    paths: [
        {d:'V', sy:0, x:0, ey:100, },
        {d:'A', sx: 0, sy:100,  ex:100, ey:100, rx:10, ry: 10, angle: 180, arc: 1, sweep: 1},  
        {d:'V', sy:0, x:100, ey:100, },
    ],
}
View Options
{ 
    samples: 100, type: 'steps', top: 20,
    paths: [
        {d:'V', sy:0, x:0, ey:100, },
        {d:'A', sx: 0, sy:100,  ex:100, ey:100, rx:10, ry: 10, angle: 180, arc: 1, sweep: 1},  
        {d:'V', sy:100, x:100, ey:0, },
        {d:'A', sx: 100, sy:0,  ex:0, ey:0, rx:10, ry: 10, angle: 180, arc: 1, sweep: 0},
    ],
}
View Options
{ 
    samples: 100, type: 'bars', top: 20, 
    paths: [ 
        {d:'V', sy: 0, x:50, ey:100 }
    ]
}
View Options
{ 
    samples: 75, type: 'mirror', top: 20, 
    paths: [ 
        {d:'L', sx: 0, sy:20, ex:100, ey:-1.5, normalize: true, minshow: 0, maxshow: 1 },
        {d:'L', sx: -100, sy:40, ex:0, ey:20, normalize: true, minshow: 0.20, maxshow: 1 },
        {d:'L', sx: -200, sy:60, ex:-100, ey:40, normalize: true, minshow: 0.40, maxshow: 1 },
        {d:'L', sx: -300, sy:80, ex:-200, ey:60, normalize: true, minshow: 0.60, maxshow: 1 },
        {d:'L', sx: -400, sy:100, ex:-300, ey:80, normalize: true, minshow: 0.80, maxshow: 1 }
    ]
}
View Options
{ 
    samples: 100, type: 'steps', top: 20, animation: true
}
View Options
{ 
    samples: 100, type: 'bars', top: 20, animation: true,
    paths: [ 
        {d:'V', sy: 0, x:50, ey:100 }
    ]
}

Polar

View Options
{ 
    samples: 90, type: 'steps',
    left: 200, top: 200, distance: 100, length: 50
}
View Options
{ 
    samples: 90, type: 'bars',
    left: 200, top: 200, distance: 100, length: 50,
    paths: [
        {d: 'L', sdeg:50, sr:0, edeg: 50, er:100 },
    ]
}
View Options
{ 
    samples: 90, type: 'mirror',
    left: 200, top: 200, distance: 100, length: 100
}
View Options
{ 
    samples: 90, type: 'steps',
    left: 200, top: 200, distance: 100, length: 100,
    startdeg: 270, enddeg: 90,
    invertdeg: true,
    invertpath: true
}
View Options
{ 
    samples: 90, type: 'steps',
    left: 200, top: 200, distance: 100, length: 100,
    paths: [
        {d:'L', sdeg:0, sr:0,  edeg:0, er:90 },
        {d:'A', sdeg:0, sr:90, edeg: 100, er:90, rx: 5, ry: 5, angle: 100, arc: 1, sweep: 1 },
        {d:'L', sdeg:100, sr:90,  edeg:100, er:0 },
    ]
}
View Options
{ 
    samples: 90, type: 'steps',
    left: 200, top: 200, distance: 100, length: 100,
    animation: true
}
View Options
{ 
    samples: 90, type: 'steps',
    left: 200, top: 200, distance: 100, length: 100,
    animation: true,
    paths: [
        {d:'L', sdeg:0, sr:0,  edeg:0, er:90 },
        {d:'A', sdeg:0, sr:90, edeg: 100, er:90, rx: 5, ry: 5, angle: 100, arc: 1, sweep: 1 },
        {d:'L', sdeg:100, sr:90,  edeg:100, er:0 },
    ]
}

Test with Microphone

Install

NPM

npm install waveform-path -s

Download

Download the last realease of repo and copy waveform-path.min.js from dist folder.

How to use

This example is the waveform of the logo of this website.

<script type="module">
                import { getAudioData, linearPath, polarPath } from "waveform-path";
            
                async function AudioPath(file) {
                    const audioData = await getAudioData(file);
            
                    const pathLogo = linearPath(audioData,{ samples: 100,  type: 'steps', top: 20 });
                    document.querySelector("#logo path").setAttribute('d', pathLogo);
            
                }
                AudioPath("hello_world.ogg");
</script>

Linear Options

Option Default Description
channel 0 Channel audio for generate wave
samples length Length of the data
height 100 Height of path
width 800 Width of path
top 0 Top margin from path to svg
left 0 Left margin from path to svg
type 'steps' 'steps', 'mirror' or 'bars'
paths [{d:'Q', sx: 0, sy:0, x: 50, y: 100, ex:100, ey:0}] Array of commands to create the path.
animation false To create animations, paths separated by commas
animationframes 10 Frames per second of the animation
normalize true Normalize audio to adjust waveform

Linear Path Options


// Lineto
{d:'L', sx: 0, sy:0, ex:50, ey:100 }

// Horitzontal
{d:'H', sx:10, y:90, ex:90}

// Vertical
{d:'V', sy:0, x:0, ey:100}

// Cubic BĂ©zier Curve - Not 100%
{d:'C', sx: 0, sy:0, x: 100, y: 100, ex:100, ey:0 },

// Quadratic BĂ©zier Curve
{d:'Q', sx: 0, sy:0, x: 50, y: 100, ex:100, ey:0}

// Arc
{d:'A', sx: 0, sy:100,  ex:100, ey:100, rx:10, ry: 10, angle: 180, arc: 1, sweep: 1}

// Z - Close Path no parameters
{d:'Z'}

sx = start % x position
x = center % x position
ex = end % x position

sy = start % y position
y = center % y position
ey = end % y position

These three extra options can be added:
minshow: 0.2  // Values 0 to 1 - Default 0
maxshow: 1 // Values 0 to 1 - Default 1
normalize: true // Normalize value y to 1. - Default false
Example: 
{d:'H', sx:10, y:90, ex:90, minshow: 0.4, maxshow: 0.6, normalize: true} // Only for y > 0.4 && y < 0.6

For arc view: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#elliptical_arc_curve

            

Polar Options

Option Default Description
channel 0 Channel audio for generate wave
samples length Length of the data
distance 50 Distance from center
length 100 Length of wave
top 0 Top margin from path to svg
left 0 Left margin from path to svg
type 'steps' 'steps', 'mirror' or 'bars'
startdeg 0 Where do you start drawing. To make it natural, 0 is equivalent to north.
enddeg 360 Where do you end drawing
invertdeg false Reverse the direction of the degrees
invertpath false Reverse the path vertically
paths [{d:'Q', sdeg: 0, sr:0, deg: 50, r: 100, edeg:100, er:0}] Array of commands to create the path.
animation false To create animations, paths separated by commas
animationframes 10 Frames per second of the animation
normalize true Normalize audio to adjust waveform

Polar Path Options


// Lineto
{d:'L', sdeg:0, sr:0,  edeg:100, er:100 },

// Cubic BĂ©zier Curve - Not 100%
{d:'C', sdeg: 0, sr:0, deg: 50, r: 100, edeg:100, er:0}

// Quadratic BĂ©zier Curve
{d:'Q', sdeg: 0, sr:0, deg: 50, r: 100, edeg:100, er:0}

// Arc
{d:'A', sdeg:80, sr:0, edeg: 0, er:0, rx: 100, ry: 100, angle: 100, arc: 0, sweep: 1 },

// Z - Close Path no parameters
{d:'Z'}

sdeg = start % deg position
deg = center % deg position
edeg = end % deg position

sr = start % radius position
r = center % radius position
er = end % radius position

These three extra options can be added:
minshow: 0.2  // Values 0 to 1 - Default 0
maxshow: 1 // Values 0 to 1 - Default 1
normalize: true // Normalize value radius to 1. - Default false
Example: 
{d:'Q', sdeg: 0, sr:0, deg: 50, r: 100, edeg:100, er:0, minshow: 0.4, maxshow: 0.6, normalize: true} // Only for y > 0.4 && y < 0.6

For arc view: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#elliptical_arc_curve