Объявление
public void SetScheduledEndTime(double time);Параметры
time | Время в секундах. |
Описание
Изменяет время окончания воспроизведения уже запланированного звука. Обратите внимание, что в зависимости от времени не все запросы на изменение расписания могут быть выполнены.
Обратите внимание, что указанное время по-прежнему является временем на абсолютной временной шкале, а это означает, что звук остановится по достижении этого времени, независимо от того, когда он был запущен. Поэтому, если у вас есть 5-секундный звук и вы хотите, чтобы он воспроизводился в момент времени T и останавливался через 3 секунды (т. е. заглушал последние 2 секунды звука), вам нужно указать время окончания, равное T+3. Эта функция полезна в музыкальных системах для преодоления разрывов в сигналах, вызванных кодеками с потерями на основе кадров.
using UnityEngine;
using System.Collections;
// Хотя это может показаться излишне сложным в случае несжатых звуков, теперь вы можете использовать
// код SavWav с https://gist.github.com/2317063 для сохранения сгенерированных клипов в новые активы,
// запустить программу один раз с указанным исходным клипом, и скрипт сгенерирует «cut1.wav» и «cut2.wav».
// Теперь их можно импортировать в Unity как активы и преобразовать в сжатые звуки.
// Поскольку психоакустическая компрессия сильно изменяет форму волны и частотный состав звуков и
// кроме того, работает в блочном режиме, это вызвало бы очень заметные всплывающие окна и щелчки, если бы мы не
// иметь звуковые данные до и после точки среза. Имея его, даже если мы в него не играем, декодер «разогревается»,
// т. е. он имеет совпадающий частотный контент до и после перехода, поэтому, по крайней мере,
// частотный спектр будет примерно одинаковым до и после перехода, поэтому щелчок будет менее слышен
// чем если бы мы просто вырезали звук без областей перекрытия 0,2 с.
// Этот метод также можно комбинировать с перекрестным затуханием для дальнейшего сглаживания любых оставшихся артефактов.
[RequireComponent(typeof(AudioSource))]
public class ExampleClass : MonoBehaviour
{
public AudioClip sourceClip;
private AudioSource audio1;
private AudioSource audio2;
private AudioClip cutClip1;
private AudioClip cutClip2;
private float overlap = 0.2F;
private int len1 = 0;
private int len2 = 0;
void Start()
{
GameObject child;
child = new GameObject("Player1");
child.transform.parent = gameObject.transform;
audio1 = child.AddComponent<AudioSource>();
child = new GameObject("Player2");
child.transform.parent = gameObject.transform;
audio2 = child.AddComponent<AudioSource>();
int overlapSamples;
if (sourceClip != null)
{
len1 = sourceClip.samples / 2;
len2 = sourceClip.samples - len1;
overlapSamples = (int)(overlap * sourceClip.frequency);
cutClip1 = AudioClip.Create("cut1", len1 + overlapSamples, sourceClip.channels, sourceClip.frequency, false, false);
cutClip2 = AudioClip.Create("cut2", len2 + overlapSamples, sourceClip.channels, sourceClip.frequency, false, false);
float[] smp1 = new float[(len1 + overlapSamples) * sourceClip.channels];
float[] smp2 = new float[(len2 + overlapSamples) * sourceClip.channels];
sourceClip.GetData(smp1, 0);
sourceClip.GetData(smp2, len1 - overlapSamples);
cutClip1.SetData(smp1, 0);
cutClip2.SetData(smp2, 0);
}
else
{
overlapSamples = (int)overlap * cutClip1.frequency;
len1 = cutClip1.samples - overlapSamples;
len2 = cutClip2.samples - overlapSamples;
}
}
void OnGUI()
{
if (GUI.Button(new Rect(10, 50, 230, 40), "Trigger source"))
audio1.PlayOneShot(sourceClip);
if (GUI.Button(new Rect(10, 100, 230, 40), "Trigger cut 1"))
audio1.PlayOneShot(cutClip1);
if (GUI.Button(new Rect(10, 150, 230, 40), "Trigger cut 2"))
audio1.PlayOneShot(cutClip2);
if (GUI.Button(new Rect(10, 200, 230, 40), "Play stitched"))
{
audio1.clip = cutClip1;
audio2.clip = cutClip2;
double t0 = AudioSettings.dspTime + 3.0F;
double clipTime1 = len1;
clipTime1 /= cutClip1.frequency;
audio1.PlayScheduled(t0);
audio1.SetScheduledEndTime(t0 + clipTime1);
Debug.Log("t0 = " + t0 + ", clipTime1 = " + clipTime1 + ", cutClip1.frequency = " + cutClip1.frequency);
Debug.Log("cutClip2.frequency = " + cutClip2.frequency + ", samplerate = " + AudioSettings.outputSampleRate);
audio2.PlayScheduled(t0 + clipTime1);
audio2.time = overlap;
}
}
}
Примечание. Если возможно, создайте перекрывающиеся клипы и используйте запланированное время окончания для первого и AudioSource.time для второго. чтобы обрезать перекрывающуюся часть, как показано в примере выше.