Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by ANGRYSH4RK · May 02, 2014 at 11:22 PM · audioaudiosourceaudioclipaudioclips array

How to generate waveform from AudioClip?

Hi there,

How would I go about generating a static waveform preview like the one seen here? Not moving, not updating as the song plays. Just a preview of the audio.

alt text

I would like to make an identical function using 2D Rectangles, NOT a debug line or gui texture.

Not a visualizer, not a debug line. A waveform preview of the entire song as seen in the image above. An example would be awesome if anyone has one to share :)!

I've had tons of trouble finding info on AudioClip.getData and how to use it, very little is out there about waveform preview generation. Tons of info however is available on visualizer generation :( which is not what i want.

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ANGRYSH4RK · May 03, 2014 at 07:45 PM 0
Share

anyone? ...

avatar image tanoshimi · May 03, 2014 at 09:56 PM 0
Share

Did you try Googling? I found several examples using the NAudio framework. Like http://www.youtube.com/watch?v=ZnFoVuOVrUQ

avatar image ANGRYSH4RK · May 03, 2014 at 10:09 PM 0
Share

Yes, but i made the mistake of googling for solutions pertaining specifically to Unity (why my search results produced little help) and forgot there's a whole nother' world of C# out there :)..thanks I see tons of tutorials now

2 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by CleverToucan · Jan 30, 2019 at 01:35 PM

I edited @Breakypower's code in the previous answer to fix a couple bugs and optimize the generation:

 public Texture2D PaintWaveformSpectrum(AudioClip audio, float saturation, int width, int height, Color col) {
     Texture2D tex = new Texture2D(width, height, TextureFormat.RGBA32, false);
     float[] samples = new float[audio.samples];
     float[] waveform = new float[width];
     audio.GetData(samples, 0);
     int packSize = ( audio.samples / width ) + 1;
     int s = 0;
     for (int i = 0; i < audio.samples; i += packSize) {
         waveform[s] = Mathf.Abs(samples[i]);
         s++;
     }
 
     for (int x = 0; x < width; x++) {
         for (int y = 0; y < height; y++) {
             tex.SetPixel(x, y, Color.black);
         }
     }
 
     for (int x = 0; x < waveform.Length; x++) {
         for (int y = 0; y <= waveform[x] * ((float)height * .75f); y++) {
             tex.SetPixel(x, ( height / 2 ) + y, col);
             tex.SetPixel(x, ( height / 2 ) - y, col);
         }
     }
     tex.Apply();
 
     return tex;
 }

It produces very lovely results for my purposes:


capture.png (36.3 kB)
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image MiniFish · Oct 11, 2019 at 02:54 AM 0
Share

hiya, just a heads up, the current code doesn't take into account of multi channel clips.

the following tweaks should fix the problem.

 // multiply it by channel to account of clips with multiple channel
         float[] samples = new float[audio.samples * audio.channels];

and change the first loop to loop through sample.length ins$$anonymous$$d

 for (int i = 0; i < samples.Length; i += packSize)
         {
             waveform[waveIndex] = $$anonymous$$athf.Abs(samples[i]);
             waveIndex++;
         }
avatar image Brogrammar MiniFish · Jul 05, 2020 at 01:03 AM 0
Share

Thanks for the fix $$anonymous$$iniFish! To save everyone else the headache I developed trying to figure out why your stuff didn't immediately work for me, remember that after applying the above changes, remember to also adjust the packsize variable. So you should also have

 int packSize = (samples.Length / width) + 1;
avatar image
1

Answer by Breakypower · Apr 06, 2018 at 09:43 PM

I do this, and it's works perfectly :

     public static float[] GetWaveform (AudioClip audio, int size, float sat) {
         float[] samples = new float[audio.samples];
         float[] waveform = new float[size];
         audio.GetData(samples, 0);
         int packSize = audio.samples / size;
 
         float max = 0f;
     int c = 0;
     int s = 0;
     for (int i = 0; i < 2 * audio.samples; i++) {
         waveform [c] += Mathf.Abs (samples [i]);
         s++;
         if (s > packSize) {
             if (max < waveform [c])
                 max = waveform [c];
             c++;
             s = 0;
         }
     }
         for (int i = 0; i < size; i++) {
             waveform [i] /= (max * sat);
             if (waveform [i] > 1f)
                 waveform [i] = 1f;
         }
 
         return waveform;
     }
 
     public static Texture2D PaintWaveformSpectrum(float[] waveform, int height, Color c) {
         Texture2D tex = new Texture2D (waveform.Length, height, TextureFormat.RGBA32, false);
 
         for (int x = 0; x < waveform.Length; x++) {
             for (int y = 0; y <= waveform [x] * (float)height / 2f; y++) {
                 tex.SetPixel (x, (height / 2) + y, c);
                 tex.SetPixel (x, (height / 2) - y, c);
             }
         }
         tex.Apply ();
 
         return tex;
     }


and use it like this:

 Texture2D tex = AudioGetter.PaintWaveformSpectrum (AudioGetter.GetWaveform (clip, 500, 1f), 50, c);
         GetComponent<Image> ().overrideSprite = Sprite.Create (tex, new Rect (0f, 0f, tex.width, tex.height), new Vector2 (0.5f, 0.5f));
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image eggecool · Jan 10, 2019 at 02:26 PM 0
Share

When I test your code I get an out of range error when c becomes 500 at waveform [c] += $$anonymous$$athf.Abs (samples [i]); Why do you have the size at 500 and why is the code able to go above that at all? I don't understand your code enough to be able to work around it so a little help would be appreciated!

avatar image coreydeaver eggecool · May 07, 2019 at 10:01 AM 0
Share

You got that error because some audio has multiple chanels, the correct code is:

 public static float[] GetWaveform(AudioClip audio, int size, float sat)
         {
             float[] samples = new float[audio.channels * audio.samples];
             float[] waveform = new float[size];
             audio.GetData(samples, 0);
             int packSize = audio.samples * audio.channels / size;
             float max = 0f;
             int c = 0;
             int s = 0;
             for (int i = 0; i < audio.channels * audio.samples; i++)
             {
                 waveform[c] += $$anonymous$$athf.Abs(samples[i]);
                 s++;
                 if (s > packSize)
                 {
                     if (max < waveform[c])
                         max = waveform[c];
                     c++;
                     s = 0;
                 }
             }
             for (int i = 0; i < size; i++)
             {
                 waveform[i] /= (max * sat);
                 if (waveform[i] > 1f)
                     waveform[i] = 1f;
             }
 
             return waveform;
         }



Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

28 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Check scilence in audio clip using FFT. 0 Answers

Is there a way to create a random Audiosource loop? 2 Answers

Breathing volume increases as player gets more tired 0 Answers

Beginners troubles with audiosource 0 Answers

Triggering multiple audio clips to play in sequence 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges