0

The default audio sample rate is 48000. Is it possible to change it to other values like 44100? I log the value of AudioSettings.outputSampleRate and it shows 48000. But it doesn't seem possible to change that value.

Thinium
  • 171
  • 1
  • 14

1 Answers1

0

Here is the code to change sample rate of Unity's AudioClip:

  1. Most simple, but very rough
  2. Averaging approach, but channels are get mixed
  3. Averaging approach for each channel (best quality)

public static AudioClip SetSampleRateSimple(AudioClip clip, int frequency)
{
    if (clip.frequency == frequency) return clip;

    var samples = new float[clip.samples * clip.channels];

    clip.GetData(samples, 0);

    var samplesLength = (int)(frequency * clip.length) * clip.channels;
    var samplesNew = new float[samplesLength];
    var clipNew = AudioClip.Create(clip.name + "_" + frequency, samplesLength, clip.channels, frequency, false);

    for (var i = 0; i < samplesLength; i++)
    {
        var index = (int) ((float) i * samples.Length / samplesLength);

        samplesNew[i] = samples[index];
    }

    clipNew.SetData(samplesNew, 0);

    return clipNew;
}

public static AudioClip SetSampleRateAverage(AudioClip clip, int frequency)
{
    if (clip.frequency == frequency) return clip;

    var samples = new float[clip.samples * clip.channels];

    clip.GetData(samples, 0);

    var samplesNewLength = (int) (frequency * clip.length) * clip.channels;
    var samplesNew = new float[samplesNewLength];
    var clipNew = AudioClip.Create(clip.name + "_" + frequency, samplesNewLength, clip.channels, frequency, false);

    var index = 0;
    var sum = 0f;
    var count = 0;

    for (var i = 0; i < samples.Length; i++)
    {
        var index_ = (int)((float)i / samples.Length * samplesNewLength);

        if (index_ == index)
        {
            sum += samples[i];
            count++;
        }
        else
        {
            samplesNew[index] = sum / count;
            index = index_;
            sum = samples[i];
            count = 1;
        }
    }

    clipNew.SetData(samplesNew, 0);

    return clipNew;
}

public static AudioClip SetSampleRate(AudioClip clip, int frequency)
{
    if (clip.frequency == frequency) return clip;
    if (clip.channels != 1 && clip.channels != 2) return clip;

    var samples = new float[clip.samples * clip.channels];

    clip.GetData(samples, 0);

    var samplesNewLength = (int) (frequency * clip.length) * clip.channels;
    var clipNew = AudioClip.Create(clip.name + "_" + frequency, samplesNewLength, clip.channels, frequency, false);

    var channelsOriginal = new List<float[]>();
    var channelsNew = new List<float[]>();

    if (clip.channels == 1)
    {
        channelsOriginal.Add(samples);
        channelsNew.Add(new float[(int) (frequency * clip.length)]);
    }
    else
    {
        channelsOriginal.Add(new float[clip.samples]);
        channelsOriginal.Add(new float[clip.samples]);

        channelsNew.Add(new float[(int) (frequency * clip.length)]);
        channelsNew.Add(new float[(int) (frequency * clip.length)]);

        for (var i = 0; i < samples.Length; i++)
        {
            channelsOriginal[i % 2][i / 2] = samples[i];
        }
    }

    for (var c = 0; c < clip.channels; c++)
    {
        var index = 0;
        var sum = 0f;
        var count = 0;
        var channelSamples = channelsOriginal[c];

        for (var i = 0; i < channelSamples.Length; i++)
        {
            var index_ = (int) ((float) i / channelSamples.Length * channelsNew[c].Length);

            if (index_ == index)
            {
                sum += channelSamples[i];
                count++;
            }
            else
            {
                channelsNew[c][index] = sum / count;
                index = index_;
                sum = channelSamples[i];
                count = 1;
            }
        }
    }

    float[] samplesNew;

    if (clip.channels == 1)
    {
        samplesNew = channelsNew[0];
    }
    else
    {
        samplesNew = new float[channelsNew[0].Length + channelsNew[1].Length];

        for (var i = 0; i < samplesNew.Length; i++)
        {
            samplesNew[i] = channelsNew[i % 2][i / 2];
        }
    }

    clipNew.SetData(samplesNew, 0);

    return clipNew;
}