Search Unity

Intermittent Errors trying to read current volume of an audio clip - using clip.GetData

Discussion in 'Scripting' started by artofmining, Apr 17, 2021.

  1. artofmining

    artofmining

    Joined:
    May 1, 2016
    Posts:
    83
    Hi
    I'm using the C# script shown below to get the current volume level of an audio sample. I'm then using the varying sample values to control a crude lipsync system.

    It works fine except that every so often I get this error in the console:

    C:\buildslave\unity\build\Modules/Audio/Public/sound/SoundManager.cpp(702) : Error executing result = instance->m_Sound->lock(offsetBytes, lengthBytes, &ptr1, &ptr2, &len1, &len2) (An invalid parameter was passed to this function. )
    UnityEngine.AudioClip:GetData(Single[], Int32)

    Its related to the line: - PMaudioSource.clip.GetData

    I have tried trapping the error using try/catch but it doesnt work.

    Anyone know what could be causing this or have a better solution to getting the audio volume level samples?

    Many thanks!
    Alan
    ==================================================

    This is the code that generates the errors

    Code (CSharp):
    1. void GetAudioVolume()
    2.     {
    3.         if (PMaudioSource!=null && PMaudioSource.clip !=null)
    4.         {
    5.             currentUpdateTime += Time.deltaTime;
    6.             if (currentUpdateTime >= updateStep)
    7.             {
    8.                 currentUpdateTime = 0f;
    9.                 try
    10.                 {
    11.                     PMaudioSource.clip.GetData(clipSampleData, PMaudioSource.timeSamples); //I read 1024 samples, which is about 80 ms on a 44khz stereo clip, beginning at the current sample position of the clip.
    12.  
    13.                 }
    14.                 catch
    15.                 {
    16.  
    17.                 }
    18.  
    19.  
    20.                 clipLoudness = 0f;
    21.                 foreach (var sample in clipSampleData)
    22.                 {
    23.                     clipLoudness += Mathf.Abs(sample);
    24.                 }
    25.                 clipLoudness /= sampleDataLength; //clipLoudness is what you are looking for
    26.                 clipLoudness *= AmplifyRatio;
    27.             }
    28.         }
    29.  
    30.     }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,692
  3. artofmining

    artofmining

    Joined:
    May 1, 2016
    Posts:
    83
    Cheers Kurt, also looking at this

    Code (CSharp):
    1. GetComponent<AudioSource>().GetOutputData(_samples, 0); // fill array with samples
    2.          int i;
    3.          float sum = 0;
    4.          for (i = 0; i < QSamples; i++)
    5.          {
    6.              sum += _samples[i] * _samples[i]; // sum squared samples
    7.          }
    8.          RmsValue = Mathf.Sqrt(sum / QSamples); // rms = square root of average
    9.          DbValue = 20 * Mathf.Log10(RmsValue / RefValue); // calculate dB
    10.          if (DbValue < -160) DbValue = -160; // clamp it to -160dB min
    11.                                              // get sound spectrum
     
  4. artofmining

    artofmining

    Joined:
    May 1, 2016
    Posts:
    83
    I resolved by the following, with less samples also.

    Code (CSharp):
    1. clipLoudness = GetAveragedVolume() * 2.5f;
    2.  
    3.                 float GetAveragedVolume()
    4.                 {
    5.                     float[] data = new float[256];
    6.                     float a = 0;
    7.                     PMaudioSource.GetOutputData(data, 0);
    8.                     foreach (float s in data)
    9.                     {
    10.                         a += Mathf.Abs(s);
    11.                     }
    12.                     return a / 256;
    13.                 }
     
    zacharyaghaizu likes this.