AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Script/Emu/AudioProvider.cs

121 lines
3.1 KiB
C#
Raw Normal View History

2024-07-04 21:06:41 +08:00
using MyNes.Core;
2024-07-16 16:30:20 +08:00
using System;
2024-07-04 21:06:41 +08:00
using System.Collections.Generic;
2024-07-16 16:30:20 +08:00
using System.Diagnostics;
2024-07-05 11:24:59 +08:00
using System.Threading;
2024-07-04 21:06:41 +08:00
using UnityEngine;
namespace AxibugEmuOnline.Client
{
public class AudioProvider : MonoBehaviour, IAudioProvider
2024-07-04 21:06:41 +08:00
{
public string Name => nameof(AudioProvider);
public string ID => Name.GetHashCode().ToString();
public bool AllowBufferChange => true;
public bool AllowFrequencyChange => true;
private bool m_isPlaying;
2024-07-17 12:50:18 +08:00
[SerializeField]
private NesCoreProxy m_coreProxy;
[SerializeField]
2024-07-05 11:24:59 +08:00
private AudioSource m_as;
2024-07-04 21:06:41 +08:00
2024-07-16 16:30:20 +08:00
private Stopwatch sw = Stopwatch.StartNew();
2024-07-17 12:43:43 +08:00
private RingBuffer<short> _buffer = new RingBuffer<short>(4096);
2024-07-05 11:24:59 +08:00
2024-07-16 16:30:20 +08:00
public double FPS { get; private set; }
2024-07-05 11:24:59 +08:00
2024-07-04 21:06:41 +08:00
public void Initialize()
{
var dummy = AudioClip.Create("dummy", 1, 1, AudioSettings.outputSampleRate, false);
2024-07-05 11:24:59 +08:00
dummy.SetData(new float[] { 1 }, 0);
m_as.clip = dummy; //just to let unity play the audiosource
m_as.loop = true;
m_as.spatialBlend = 1;
2024-07-05 11:24:59 +08:00
m_as.Play();
2024-07-04 21:06:41 +08:00
}
float lastData = 0;
void OnAudioFilterRead(float[] data, int channels)
2024-07-04 21:06:41 +08:00
{
int step = channels;
2024-07-16 17:46:07 +08:00
2024-07-17 12:43:43 +08:00
var bufferCount = _buffer.Available();
if (bufferCount < 4096)
{
double fps = 1 / 61d;
NesEmu.SetFramePeriod(ref fps);
}
else if (bufferCount > 8124)
{
double fps = 1 / 59d;
NesEmu.SetFramePeriod(ref fps);
}
else
{
NesEmu.RevertFramePeriod();
}
for (int i = 0; i < data.Length; i += step)
{
2024-07-17 12:43:43 +08:00
float rawFloat = lastData;
if (_buffer.TryRead(out short rawData))
rawFloat = rawData / 124f;
data[i] = rawFloat;
for (int fill = 1; fill < step; fill++)
data[i + fill] = rawFloat;
lastData = rawFloat;
}
2024-07-04 21:06:41 +08:00
}
2024-07-16 16:30:20 +08:00
private TimeSpan lastElapsed;
2024-07-05 11:24:59 +08:00
public void SubmitSamples(ref short[] buffer, ref int samples_a)
2024-07-04 21:06:41 +08:00
{
2024-07-16 16:30:20 +08:00
var current = sw.Elapsed;
var delta = current - lastElapsed;
lastElapsed = current;
FPS = 1d / delta.TotalSeconds;
for (int i = 0; i < samples_a; i++)
2024-07-05 11:24:59 +08:00
{
2024-07-17 12:43:43 +08:00
_buffer.Write(buffer[i]);
2024-07-05 11:24:59 +08:00
}
2024-07-04 21:06:41 +08:00
}
public void TogglePause(bool paused)
{
m_isPlaying = !paused;
}
public void GetIsPlaying(out bool playing)
{
playing = m_isPlaying;
}
public void ShutDown()
{
}
public void Reset()
{
}
public void SignalToggle(bool started)
{
}
public void SetVolume(int Vol)
{
}
}
}