ue3dUnity通过直接编辑AudioClip学习声音数据的结构

Unity通过直接编辑AudioClip学习声音数据的结构

分类:
ue3d - Unity通过直接编辑AudioClip学习声音数据的结构

下面通过直接编辑Unity的AudioClip数据来学习声音数据的结构。

采样和量化简介

在本文中,将通过直接编辑Unity的Audio Clip数据、改变音量、编辑特定秒数的数据来学习声音数据的结构。

但在此之前,需要先简单总结一下本节关于声音数据的最低限度前提知识。

现在,考虑以下波形所代表的声音,现实世界中的声音可以用这样的连续波来表示。

ue3d - Unity通过直接编辑AudioClip学习声音数据的结构

接下来,考虑将其转换为数字数据,由于数字数据只是数值的集合,因此以规则的时间间隔将波分开并转换为每个时间间隔的数据,这称为抽样。

ue3d - Unity通过直接编辑AudioClip学习声音数据的结构

另外,一秒内采样多少次称为频率,以赫兹(Hz)为单位表示。44100 Hz,常用于声音数据,表示数据每秒采样 44100 次。

在以这种方式划分成固定时间间隔之后,信号电平被转换为每个时间间隔的数字数据。由于数字数据也是离散数,因此结果是具有如下层次的数据集合,这称为量化。

ue3d - Unity通过直接编辑AudioClip学习声音数据的结构

用于表示一段采样数据的比特数称为量化比特数。

综上所述,可以说如果增加频率和量化位数,就可以更准确地再现实际声音(数据量自然会增加)。

控制音量

现在了解了基础知识,来实际编辑音频剪辑。

可以通过调用AudioClip.GetData()获取所有样本的值,该值是一个浮点数数组,每个浮点值代表一个采样数据(如前一节所述,以固定间隔分隔的数据)。

采样数据由-1到1之间的值表示,因此,如果可以像下图那样写0.5,信号电平减半,也就是音量减半。

using UnityEngine;

public class AudioExample : MonoBehaviour
{
    [SerializeField] private AudioSource _source;

    private void Start()
    {
        var clip = _source.clip;
        ChangeAudioClipVolume(clip, 0.5f, true);
    }
    
    private static void ChangeAudioClipVolume(AudioClip clip, float magnification)
    {
        // number of samples = value of clip.samples x number of channels (1 for mono, 2 for stereo)
        var samples = new float[clip.samples * clip.channels];

        clip.GetData(samples, 0);
        for (var i = 0; i < samples.Length; i++)
        {
            // Multiply the values of all samples by the value of the argument
            samples[i] *= magnification;
        }

        clip.SetData(samples, 0);
    }
}

需要在加载时解压

如上获取数据时需要注意的一点AudioClip.GetData()是,AudioClip的Load Type必须是Decompress On Load。

ue3d - Unity通过直接编辑AudioClip学习声音数据的结构

其他任何东西都会为所有样本返回零值。

只调整一个频道

现在,只播放一个频道,假设音频文件是立体声的。

ue3d - Unity通过直接编辑AudioClip学习声音数据的结构

在立体声的情况下,如前一节获取的样本数据格式为第一个样本左,第一个样本右,第二个样本左,第二个样本右,依此类推。

ue3d - Unity通过直接编辑AudioClip学习声音数据的结构

因此,如果像下图这样只处理能被2整除的索引,则只能处理左边,反之,则只能处理右边。

using UnityEngine;

public class AudioExample : MonoBehaviour
{
    [SerializeField] private AudioSource _source;

    private void Start()
    {
        var clip = _source.clip;
        ChangeAudioClipVolume(clip, 0.5f, true);
    }
    
    private static void ChangeAudioClipVolume(AudioClip clip, float magnification, bool left)
    {
        var samples = new float[clip.samples * clip.channels];
        clip.GetData(samples, 0);
        for (var i = 0; i < samples.Length; i++)
        {
            if (left && i % 2 != 0)
            {
                continue;
            }
            if (!left && i % 2 != 1)
            {
                continue;
            }
            samples[i] *= magnification;
        }

        clip.SetData(samples, 0);
    }
}

当播放这个时,应该能够确认只有左耳的声音被减弱了。

处理特定的时间

最后,编辑特定秒数的数据。

为此,AudioClip.frequency请从每秒样本数可以表示为频率*通道数,因此可以只处理特定秒数的数据,如下所示。

using UnityEngine;

public class AudioExample : MonoBehaviour
{
    [SerializeField] private AudioSource _source;

    private void Start()
    {
        var clip = _source.clip;
        ChangeAudioClipVolume(clip, 0.1f, 5.0f);
    }
    
    private static void ChangeAudioClipVolume(AudioClip clip, float magnification, float durationSec)
    {
        var samples = new float[clip.samples * clip.channels];
        clip.GetData(samples, 0);
        
        // Samples per second = sampling frequency * number of channels
        var samplesPerSec = clip.frequency * clip.channels;
        var limit = samplesPerSec * durationSec;
        
        for (var i = 0; i < limit; i++)
        {
            samples[i] *= magnification;
        }

        clip.SetData(samples, 0);
    }
}

如果播放这个,会发现只有前5秒声音比较小。

以上是关于通过直接编辑Unity的AudioClip数据来学习声音数据的结构的全部内容,如果你有任何反馈,请随时在本页面下方留言。

相关信息

  • 类型:知识
  • 字数:802
  • 字符:4434
  • 适用软件:Unity2019.4.0
  • 说明:无
  • 编号:164241

热门内容

提示:3D天堂作为服务提供者,尊重网络版权及知识产权,对某些行为的发生不具备充分的监控能力,若无意间侵犯到您的权利,请 联系我们,我们会在收到信息后尽快给予处理。

本站文章版权归本站自创作者所有,未经允许不得转载!