0

我正在尝试统一编程一个准确的节拍器。我知道,已经有一些问题,但我找不到我的问题的解决方案。我的第一个幼稚实现使用了 Play() 或 PlayOneShot()。但不幸的是,它不是很准确。所以我想,我可以用 PlayScheduled() 和缓冲时间来实现它。就像在这个例子中一样:http ://www.schmid.dk/talks/2014-05-21-Nordic_Game_Jam/Schmid-2014-05-21-NGJ-140.pdf 但这也不起作用,我也没有声音完全没有,或者声音有时会被切断,就好像声音的开头没有播放一样。为什么没有播放预定的声音?

到目前为止,这是我的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(AudioSource))]

public class inaccurateMetronome : MonoBehaviour {

public double bpm = 140.0F;

public AudioClip sound0;
public AudioSource audio0;

bool running = false;
bool ticked = false;

public double buff = 0.2d;
double timePerTick;
double nextTick;
double dspTime;


void Start () {
    double startTick = AudioSettings.dspTime;
    nextTick = startTick + buff;
    audio0 = GetComponent<AudioSource>();
    audio0.clip = sound0;

}

public void toggleMetronome() {
    if (running)
        stopMetronome();
    else
        startMetronome();
}

public void startMetronome() {
    if (running) {
        Debug.LogError("Metronome: already running");
        return;
    } else {
        running = true;
        timePerTick = 60.0f / bpm;
        nextTick = AudioSettings.dspTime + buff;
        Debug.Log("Metronome started");
    }
}

public void stopMetronome() {
    if (!running) {
        Debug.LogError("Metronome: not yet running");
        return;
    } else {
        running = false;
        Debug.Log("Metronome stopped");
    }
}

public void setBpm(double bpm){
    this.bpm = bpm;
    this.timePerTick = 60.0f / bpm;
}


void FixedUpdate() {
    dspTime = AudioSettings.dspTime;
    if ( running && dspTime + buff >= nextTick) {
        ticked = false;
        nextTick += timePerTick;
    }
    else if ( running && !ticked && nextTick >= AudioSettings.dspTime ) {
                audio0.PlayOneShot(sound0, 1);
                Debug.Log("Tick");
            ticked = true;
        }
    }

}

如果有人可以帮助我,那就太好了。谢谢!

4

1 回答 1

0

直接使用Unity 文档中的一个 如果您想播放自己的声音,只需在Debug.Log().

using UnityEngine;
    using

 System.Collections;

    // The code example shows how to implement a metronome that procedurally generates the click sounds via the OnAudioFilterRead callback.
    // While the game is paused or the suspended, this time will not be updated and sounds playing will be paused. Therefore developers of music scheduling routines do not have to do any rescheduling after the app is unpaused

    [RequireComponent(typeof(AudioSource))]
    public class ExampleClass : MonoBehaviour
    {
        public double bpm = 140.0F;
        public float gain = 0.5F;
        public int signatureHi = 4;
        public int signatureLo = 4;
        private double nextTick = 0.0F;
        private float amp = 0.0F;
        private float phase = 0.0F;
        private double sampleRate = 0.0F;
        private int accent;
        private bool running = false;
        void Start()
        {
            accent = signatureHi;
            double startTick = AudioSettings.dspTime;
            sampleRate = AudioSettings.outputSampleRate;
            nextTick = startTick * sampleRate;
            running = true;
        }

        void OnAudioFilterRead(float[] data, int channels)
        {
            if (!running)
                return;

            double samplesPerTick = sampleRate * 60.0F / bpm * 4.0F / signatureLo;
            double sample = AudioSettings.dspTime * sampleRate;
            int dataLen = data.Length / channels;
            int n = 0;
            while (n < dataLen)
            {
                float x = gain * amp * Mathf.Sin(phase);
                int i = 0;
                while (i < channels)
                {
                    data[n * channels + i] += x;
                    i++;
                }
                while (sample + n >= nextTick)
                {
                    nextTick += samplesPerTick;
                    amp = 1.0F;
                    if (++accent > signatureHi)
                    {
                        accent = 1;
                        amp *= 2.0F;
                    }
                    Debug.Log("Tick: " + accent + "/" + signatureHi);
                }
                phase += amp * 0.3F;
                amp *= 0.993F;
                n++;
            }
        }
    }
于 2017-11-20T17:38:49.267 回答