# SVG from Audio Amplitude?

**URL:** <https://discourse.processing.org/t/svg-from-audio-amplitude/44633>\
**Category:** Libraries\
**Created:** [June 24, 2024, 4:45am UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633 "2024-06-24T04:45:23Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![bdon](https://avatars.discourse-cdn.com/v4/letter/b/7ea924/32.png) [@bdon](https://discourse.processing.org/u/bdon)\
**Post date:** [June 24, 2024, 4:45am UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/1 "2024-06-24T04:45:23Z")

</div>

Hi -  
I’d like to render a small audio file (.wav) into an SVG represention of its amplitude.  
Is this possible? Is Processing the best tool for the job or is there something else that would be better for this purpose?  
Thanks!

---

<div class="post-metadata">

**Author:** ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)\
**Post date:** [June 24, 2024, 2:49pm UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/2 "2024-06-24T14:49:28Z")

</div>

> [@bdon](#):
>
> I’d like to render a small audio file (.wav) into an SVG represention of its amplitude.

Do you have code to turn a .wav file into an image? Once you’ve got the image then use this reference to convert to SVG: [https://processing.org/reference/libraries/svg/index.html](https://processing.org/reference/libraries/svg/index.html)

---

<div class="post-metadata">

**Author:** ![bdon](https://avatars.discourse-cdn.com/v4/letter/b/7ea924/32.png) [@bdon](https://discourse.processing.org/u/bdon)\
**Post date:** [June 24, 2024, 4:36pm UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/3 "2024-06-24T16:36:20Z")

</div>

I don’t have code that can do that. I’m unclear how one would do it in Processing.

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [June 24, 2024, 5:10pm UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/4 "2024-06-24T17:10:21Z")

</div>

> [@bdon](#):
>
> I don’t have code that can do that. I’m unclear how one would do it in Processing.

There are resources (tutorials, references, examples, etc.) here:

> **[Welcome to Processing!](https://processing.org)**
>
> Processing is a flexible software sketchbook and a language for learning how to code. Since 2001, Processing has promoted software literacy within the visual arts and visual literacy within technology…

To get you started:

> **[Sound](https://processing.org/tutorials/sound/)**
>
> Learn how to play, analyze, and synthesize sound with the Sound Library.

> **[Sound / Libraries](https://processing.org/reference/libraries/sound/index.html)**
>
> Playback audio files, audio input, synthesize sound, and effects.

Examples that come with Processing Development Environment:

![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/f/b/fb1b255e5323c9e805955c0d858376e75c9f23ef.png)

`:)`

---

<div class="post-metadata">

**Author:** ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)\
**Post date:** [June 24, 2024, 5:15pm UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/5 "2024-06-24T17:15:38Z")

</div>

1. You can get started here: [https://processing.org/reference/libraries/sound/Amplitude.html](https://processing.org/reference/libraries/sound/Amplitude.html) .
2. Add your sound file with code that looks like this:

```auto
  sample = new SoundFile(this, "xxxxx.wav");
  sample.loop();
// Create an Input stream which is routed into the Amplitude analyzer
  amp = new Amplitude(this);
  amp.input(sample);

```

1. In draw() plot the amplitude\*200 with vertical lines.
2. Save image of screen.
3. Convert image to svg.

 ![amplitude](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/9/8/984f47f41caa9afdcf86ba01ccd107da8f70f590.png)

---

<div class="post-metadata">

**Author:** ![micuat](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micuat/32/19407_2.png) [@micuat](https://discourse.processing.org/u/micuat)\
**Post date:** [June 24, 2024, 5:53pm UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/6 "2024-06-24T17:53:18Z")

</div>

note that loading SVG can get slow if you have many lines (which is not a problem on Processing canvas). You should start with a short sound sample.

---

<div class="post-metadata">

**Author:** ![bdon](https://avatars.discourse-cdn.com/v4/letter/b/7ea924/32.png) [@bdon](https://discourse.processing.org/u/bdon)\
**Post date:** [June 25, 2024, 2:39am UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/7 "2024-06-25T02:39:25Z")

</div>

Hi there -  
Thank you for the ideas - but I’m not sure this is exactly what I’m after. I think the “Sound” library is mainly for creating a real-time representation of sound, as it is playing - and I’m hoping to render a short audio file. I also think the vertical lines might not be an accurate representation of the waveform. I’m hoping to convert a waveform directly into a vector file.

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [June 25, 2024, 3:17am UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/8 "2024-06-25T03:17:03Z")

</div>

> [@bdon](#):
>
> I’m hoping to convert a waveform directly into a vector file.

First you need to extract data from the wav file.

I came across this:

> <https://stackoverflow.com/questions/27517265/graphing-wav-file-in-java>

And got this working with Processing:

```auto
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.AudioInputStream;

void setup()
{

  File file = new File(sketchPath() + "/data/" + "loonwail.wav");
  AudioInputStream ais = null;
  try {
    ais = AudioSystem.getAudioInputStream(file);
    int frameLength = (int) ais.getFrameLength();
    int frameSize = (int) ais.getFormat().getFrameSize();
    byte[] eightBitByteArray = new byte[frameLength * frameSize];

    int result = ais.read(eightBitByteArray);

    int channels = ais.getFormat().getChannels();
    int[][] samples = new int[channels][frameLength];

    int sampleIndex = 0;
    for (int t = 0; t < eightBitByteArray.length; ) {
      for (int channel = 0; channel < channels; channel++) {
        int low = (int) eightBitByteArray[t];
        t++;
        int high = (int) eightBitByteArray[t];
        t++;
        int sample = getSixteenBitSample(high, low);

        println(hex(sample));

        samples[channel][sampleIndex] = sample;
      }
      sampleIndex++;
    }
  }
  catch (Exception exp) {

    exp.printStackTrace();
  }
  finally {

    try {
      ais.close();
    }
    catch (Exception e) {
    }
  }
}

int getSixteenBitSample(int high, int low)
{
  return (high << 8) + (low & 0x00ff);
}

```

The above may not be a solution but was a first step for me exploring this.

Have fun!

`:)`

---

<div class="post-metadata">

**Author:** ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)\
**Post date:** [June 25, 2024, 3:19am UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/9 "2024-06-25T03:19:35Z")

</div>

There are online converters that you can use to visualize the waveform of an audio file. You might want to use them instead of using the Sound library.

The output from the amplitude demo is a series of y values that you can use to draw a curve if that’s what you’d rather have.

---

<div class="post-metadata">

**Author:** ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)\
**Post date:** [June 25, 2024, 5:14am UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/10 "2024-06-25T05:14:25Z")

</div>

Where’s the output? This is what I see on a mac:  
 ![Screenshot 2024-06-25 at 12.12.39 AM](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/4/c/4cc035aa2e07d5deb79a8207152bb76eec4d2108.png)

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [June 26, 2024, 7:47am UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/11 "2024-06-26T07:47:01Z")

</div>

Hello @bdon,

> [@glv](#):
>
> The above may not be a solution but was a first step for me exploring this.

That code was a dead end but a worthwhile exploration for me and will keep exploring. Not any time soon though.

A solution to extract meaningful WAV file data is still needed.

I have written code to convert data to an SVG (used some sample data from sine waves) using the Processing library and the SVG vectors will represent the data.  
The Processing SVG library only saves an SVG from the last frame so I stored data in an _ArrayList_ and generated the shape and an SVG in a single frame; one vector for each data point.

I will revisit this topic when I have more time.

`:)`

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [June 26, 2024, 11:17pm UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/13 "2024-06-26T23:17:25Z")

</div>

Hello @bdon,

This reference was _very helpful_:

> **[Manually parsing a wave file in Java](https://sangorrin.blogspot.com/2014/03/reading-wav-file-in-java.html)**
>
> In Java it is possible to get data directly from an audio device, audio file or URL (see examples here and here ) through a standard packag...

I modified it and was able to plot data:

```auto
//https://sangorrin.blogspot.com/2014/03/reading-wav-file-in-java.html

import java.io.*;

int x, y, xlast, ylast;

void setup()
  {
  size(1000, 200);  
  int bytes, cursor, unsigned;
  try {
      FileInputStream s = new FileInputStream(sketchPath() + "/data/" + "loonwail.wav");
      BufferedInputStream b = new BufferedInputStream(s);
      byte[] data = new byte[width];
      b.skip(44);
      cursor = 0;
      //while ((bytes = b.read(data)) > 0)       
      while ((bytes = b.read(data)) > 0 && cursor <width) 
        {
        // do something
        for (int i=0; i<bytes; i++) 
          {
          xlast = x;
          ylast = y;  
          unsigned = data[i] & 0xFF; // Java..
          System.out.println(cursor + " " + unsigned);
          cursor++;
          strokeWeight(2);
          x = 5*i;
          y = 5*(unsigned-128)+height/2;
          //point(5*i, y);
          line(x, y, xlast, ylast);
          }
      }
      b.read(data);
      b.close();
    }
  catch(Exception e)
    {
    e.printStackTrace();
    }    
  }

void draw()
{
}

```

Output:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/9/2/925a417cb3ceb5d1acb4159565302aba93779351.png)

Add a few lines of code from here and you can generate an SVG:

> **[SVG Export / Libraries](https://processing.org/reference/libraries/svg/index.html)**
>
> Create SVG files.

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/f/9/f932c01693f5a138adc5a313a07d521befcd00ab.png)

`:)`

---

<div class="post-metadata">

**Author:** ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)\
**Post date:** [June 27, 2024, 1:08am UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/14 "2024-06-27T01:08:10Z")

</div>

On my mac I have no output from this demo with a direct copy/paste; the only thing I changed is the filename to another file with the _.wav_ extension (inside a ‘data’ folder).

**Addendum:**  
The code does run with an '_.mp3’_ file if I increase the window size and reverse the sign for the y value, ie change from: `y = 5*(unsigned-128)+height/2;` to: `y = -5*(unsigned-128);` Observation:  
unsigned is always zero with println(). Maybe real value is a float that’s always less than 1 and it gets rounded to zero?

**Output(macos):**

 ![mp3](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/e/1/e1a2ff28c3bf41609deb5c7ea503f1bad2a758ec.jpeg)

---

<div class="post-metadata">

**Author:** ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)\
**Post date:** [June 27, 2024, 1:39am UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/15 "2024-06-27T01:39:35Z")

</div>

Is your posted output upside down?

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [June 30, 2024, 11:18am UTC](https://discourse.processing.org/t/svg-from-audio-amplitude/44633/16 "2024-06-30T11:18:17Z")

</div>

> [@glv](#):
>
> That code was a dead end but a worthwhile exploration for me and will keep exploring. Not any time soon though.

And the exploring continues… turns out it was not a dead end!

It works with a 16-bit WAV file (code to generate SVG can be added):

```auto
// Code adapted by glv from:
// https://stackoverflow.com/questions/27517265/graphing-wav-file-in-java

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.AudioInputStream;

void setup()
  {
  size(700, 400);
  background(32);
  
  // Download it once and then comment these lines!
  //byte[] data = loadBytes("https://github.com/processing/processing-sound/raw/main/examples/Soundfile/StereoSample/data/stereo441hzoutofphase.wav");
  //saveBytes(sketchPath() + "/data/" + "stereo441hzoutofphase.wav", data);
  
  File file = new File(sketchPath() + "/data/" + "stereo441hzoutofphase.wav");
  AudioInputStream ais = null;
  try {
    ais = AudioSystem.getAudioInputStream(file);
    int frameLength = (int) ais.getFrameLength();
    int frameSize = (int) ais.getFormat().getFrameSize();
    
    println(frameLength);
    println(frameSize);
    println(frameLength * frameSize);
    
    byte[] eightBitByteArray = new byte[frameLength * frameSize];

    int result = ais.read(eightBitByteArray);
    println(result);
    
    int channels = ais.getFormat().getChannels();
    //int[][] samples = new int[channels][frameLength];

    float max=0, min=0;
    float y0, y1;
    
    strokeWeight(2);
    stroke(128);
    line(0, height/4, width, height/4);
    line(0, 3*height/4, width, 3*height/4);

    //int sampleIndex = 0;
    //for (int t = 0; t < eightBitByteArray.length; ) 
    for (int t = 0; t < 1324; ) 
      {
      for (int channel = 0; channel < channels; channel++) 
        {
        int low = (int) eightBitByteArray[t];
        t++;
        int high = (int) eightBitByteArray[t];
        t++;
        int sample = getSixteenBitSample(high, low);
        
        int vol = 50;
        
        strokeWeight(2);
        if (channel == 0) 
          {
          y0 = sample/4095.0*vol + height/4;
          stroke(255, 0, 0);
          point (t/2, y0);
          }
        
        else if (channel == 1)
          {
          y1 = sample/4095.0*vol + 3*height/4;
          stroke(255, 255, 0);
          point (t/2, y1);
          }
        
        if (sample > max) max = sample;
        if (sample < min) min = sample;
        
        // It is 16-bit signed data!

        // Only for debug:  
        //println(channel, sample);

        //samples[channel][sampleIndex] = sample;
        }
        //sampleIndex++;
      }
      println(min, max);
    }
  catch (Exception exp) 
    {
    exp.printStackTrace();
    }    
  finally 
    {
    try 
      {
      ais.close();
      }
    catch (Exception e) 
      {
      }
    }
  }

int getSixteenBitSample(int high, int low)
  {
  return (high << 8) + (low & 0x00ff);
  }

```

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/1/1/1165b70c70aa20b13bcbf92a2de21839deccebc5.png)

`:)`
