音频解决(缺少追赶机制)

This commit is contained in:
ALIENJACK\alien 2024-07-05 11:24:59 +08:00
parent 28e0071191
commit 2868c02c16
9 changed files with 152 additions and 135 deletions

View File

@ -25,5 +25,7 @@ namespace MyNes.Core
void SignalToggle(bool started);
void SetVolume(int Vol);
void Update();
}
}

View File

@ -37,5 +37,7 @@ namespace MyNes.Core
void ToggleFPS(bool show_fps);
void ApplyFilter();
void Update();
}
}

View File

@ -167,8 +167,9 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: ac8cd27a180bf3e489b2ca27c821bffe, type: 3}
m_Name:
m_EditorClassIdentifier:
AS: {fileID: 1379369699}
DrawImage: {fileID: 730321751}
DO: {fileID: 1379369700}
DO: {fileID: 0}
Fps: {fileID: 1680039028}
--- !u!1 &708549044
GameObject:
@ -610,7 +611,6 @@ GameObject:
m_Component:
- component: {fileID: 1379369698}
- component: {fileID: 1379369699}
- component: {fileID: 1379369700}
m_Layer: 5
m_Name: Audio
m_TagString: Untagged
@ -733,19 +733,6 @@ AudioSource:
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
--- !u!114 &1379369700
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1379369697}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f25db9f5a7339c34f94e6e978be38c82, type: 3}
m_Name:
m_EditorClassIdentifier:
Gain: 0.05
--- !u!1 &1680039027
GameObject:
m_ObjectHideFlags: 0

View File

@ -2,10 +2,12 @@ using MyNes.Core;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Threading;
using UnityEditor.PackageManager.UI;
using UnityEngine;
using UnityEngine.Profiling;
namespace AxibugEmuOnline.Client
{
@ -20,25 +22,47 @@ namespace AxibugEmuOnline.Client
public bool AllowFrequencyChange => true;
private bool m_isPlaying;
private AudioSource m_as;
private int samples_added;
private Queue<(float[], int)> queues = new Queue<(float[], int)>();
private Queue<float> _buffer = new Queue<float>();
public void Initialize()
{
m_as = NesCoreProxy.Instance.AS;
m_as.clip = AudioClip.Create("nes wav", 48000 * 2, 1, 48000, true, OnAudioFilterRead);
m_as.loop = true;
m_as.playOnAwake = false;
m_as.spatialBlend = 0f;
m_as.Play();
}
public void Update() { }
private void OnAudioFilterRead(float[] data)
{
lock (_buffer)
{
for (int i = 0; i < data.Length; i++)
{
data[i] = _buffer.Count > 0 ? _buffer.Dequeue() : 0;
}
}
}
public void SubmitSamples(ref short[] buffer, ref int samples_a)
{
NesCoreProxy.Instance.DO.Play(buffer.Take(samples_a).SelectMany(s => toBytes(s)).ToArray());
}
public byte[] toBytes(short value)
{
byte[] temp = new byte[2];
//temp[0] = (byte)(value >> 8);
temp[0] = temp[1] = (byte)((uint)value & 0xFFu);
return temp;
lock (_buffer)
{
foreach (var a in buffer.Take(samples_a).ToArray())
{
var floatData = (float)a / 124;
_buffer.Enqueue(floatData);
}
}
}
public void TogglePause(bool paused)

View File

@ -66,119 +66,118 @@ public class DefaultAudioOutput : MonoBehaviour
{
_pipeStream.Write(data, 0, data.Length);
}
}
private class PipeStream : Stream
public class PipeStream : Stream
{
private readonly Queue<byte> _buffer = new Queue<byte>();
private long _maxBufferLength = 8192;
public long MaxBufferLength
{
private readonly Queue<byte> _buffer = new Queue<byte>();
private long _maxBufferLength = 8192;
get { return _maxBufferLength; }
set { _maxBufferLength = value; }
}
public long MaxBufferLength
public new void Dispose()
{
_buffer.Clear();
}
public override void Flush()
{
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
if (offset != 0)
throw new NotImplementedException("Offsets with value of non-zero are not supported");
if (buffer == null)
throw new ArgumentException("Buffer is null");
if (offset + count > buffer.Length)
throw new ArgumentException("The sum of offset and count is greater than the buffer length. ");
if (offset < 0 || count < 0)
throw new ArgumentOutOfRangeException("offset", "offset or count is negative.");
if (count == 0)
return 0;
int readLength = 0;
lock (_buffer)
{
get { return _maxBufferLength; }
set { _maxBufferLength = value; }
}
public new void Dispose()
{
_buffer.Clear();
}
public override void Flush()
{
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
if (offset != 0)
throw new NotImplementedException("Offsets with value of non-zero are not supported");
if (buffer == null)
throw new ArgumentException("Buffer is null");
if (offset + count > buffer.Length)
throw new ArgumentException("The sum of offset and count is greater than the buffer length. ");
if (offset < 0 || count < 0)
throw new ArgumentOutOfRangeException("offset", "offset or count is negative.");
if (count == 0)
return 0;
int readLength = 0;
lock (_buffer)
// fill the read buffer
for (; readLength < count && Length > 0; readLength++)
{
// fill the read buffer
for (; readLength < count && Length > 0; readLength++)
{
buffer[readLength] = _buffer.Dequeue();
}
buffer[readLength] = _buffer.Dequeue();
}
return readLength;
}
private bool ReadAvailable(int count)
{
return (Length >= count);
}
return readLength;
}
public override void Write(byte[] buffer, int offset, int count)
private bool ReadAvailable(int count)
{
return (Length >= count);
}
public override void Write(byte[] buffer, int offset, int count)
{
if (buffer == null)
throw new ArgumentException("Buffer is null");
if (offset + count > buffer.Length)
throw new ArgumentException("The sum of offset and count is greater than the buffer length. ");
if (offset < 0 || count < 0)
throw new ArgumentOutOfRangeException("offset", "offset or count is negative.");
if (count == 0)
return;
lock (_buffer)
{
if (buffer == null)
throw new ArgumentException("Buffer is null");
if (offset + count > buffer.Length)
throw new ArgumentException("The sum of offset and count is greater than the buffer length. ");
if (offset < 0 || count < 0)
throw new ArgumentOutOfRangeException("offset", "offset or count is negative.");
if (count == 0)
while (Length >= _maxBufferLength)
return;
lock (_buffer)
// queue up the buffer data
foreach (byte b in buffer)
{
while (Length >= _maxBufferLength)
return;
// queue up the buffer data
foreach (byte b in buffer)
{
_buffer.Enqueue(b);
}
_buffer.Enqueue(b);
}
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return true; }
}
public override long Length
{
get { return _buffer.Count; }
}
public override long Position
{
get { return 0; }
set { throw new NotImplementedException(); }
}
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return true; }
}
public override long Length
{
get { return _buffer.Count; }
}
public override long Position
{
get { return 0; }
set { throw new NotImplementedException(); }
}
}

View File

@ -34,7 +34,7 @@ namespace AxibugEmuOnline.Client
return color;
}
public void Draw()
public void Update()
{
var colors = m_texRawBuffer.Select(w => GetColor((uint)w)).ToArray();
m_rawBufferWarper.SetPixels(colors);

View File

@ -1,4 +1,5 @@
using MyNes.Core;
using MyNes;
using MyNes.Core;
using System.IO;
using UnityEngine;
@ -6,15 +7,15 @@ namespace AxibugEmuOnline.Client.Manager
{
public class AppEmu : IFileManager
{
public UguiVideoProvider UguiVideo { get; private set; }
public AudioProvider Audio { get; private set; }
public IVideoProvider UguiVideo { get; private set; }
public IAudioProvider Audio { get; private set; }
public void Init()
{
MyNesMain.Initialize(this);
NesEmu.LoadGame("E:/rzg4.nes", out var successed, true);
UguiVideo = MyNesMain.VideoProvider as UguiVideoProvider;
Audio = MyNesMain.AudioProvider as AudioProvider;
UguiVideo = MyNesMain.VideoProvider;
Audio = MyNesMain.AudioProvider;
var fps_nes_missle = 1.0 / 59.0;
NesEmu.SetFramePeriod(ref fps_nes_missle);
@ -22,7 +23,8 @@ namespace AxibugEmuOnline.Client.Manager
public void Update()
{
UguiVideo.Draw();
UguiVideo.Update();
Audio.Update();
double t = Time.deltaTime;
NesEmu.SetFramePeriod(ref t);

View File

@ -10,6 +10,7 @@ namespace AxibugEmuOnline.Client
{
public static NesCoreProxy Instance { get; private set; }
public AudioSource AS;
public RawImage DrawImage;
public DefaultAudioOutput DO;
public Text Fps;

View File

@ -63,6 +63,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.Services.Core.Network
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.Performance.Profile-Analyzer.Editor", "Unity.Performance.Profile-Analyzer.Editor.csproj", "{F57AB79F-532A-EBC2-871B-64C9FD27FEA9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AxibugEmuOnline.Client", "AxibugEmuOnline.Client.csproj", "{59C211A4-B928-7505-AF2E-6C604DAB3622}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.Services.Core.Scheduler", "Unity.Services.Core.Scheduler.csproj", "{2598AAB1-DA3E-A2AE-B060-D1BAF7BBE4BC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.VSCode.Editor", "Unity.VSCode.Editor.csproj", "{5A8F066D-8FFA-AFC1-1E8E-0DE9AEAE676F}"
@ -71,8 +73,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.TestTools.CodeCoverag
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.Settings.Editor", "Unity.Settings.Editor.csproj", "{541572F4-E051-F4F8-9B39-87BFA550E13A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AxibugEmuOnline.Client", "AxibugEmuOnline.Client.csproj", "{59C211A4-B928-7505-AF2E-6C604DAB3622}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.Services.Core.Registration", "Unity.Services.Core.Registration.csproj", "{A5C76622-FE9B-BD41-A430-5208CCE95FDA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.Services.Core.Telemetry", "Unity.Services.Core.Telemetry.csproj", "{7F93B805-8A3C-D81B-FEE7-A4CE542AB2D2}"
@ -219,6 +219,10 @@ Global
{F57AB79F-532A-EBC2-871B-64C9FD27FEA9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F57AB79F-532A-EBC2-871B-64C9FD27FEA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F57AB79F-532A-EBC2-871B-64C9FD27FEA9}.Release|Any CPU.Build.0 = Release|Any CPU
{59C211A4-B928-7505-AF2E-6C604DAB3622}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{59C211A4-B928-7505-AF2E-6C604DAB3622}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59C211A4-B928-7505-AF2E-6C604DAB3622}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59C211A4-B928-7505-AF2E-6C604DAB3622}.Release|Any CPU.Build.0 = Release|Any CPU
{2598AAB1-DA3E-A2AE-B060-D1BAF7BBE4BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2598AAB1-DA3E-A2AE-B060-D1BAF7BBE4BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2598AAB1-DA3E-A2AE-B060-D1BAF7BBE4BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -235,10 +239,6 @@ Global
{541572F4-E051-F4F8-9B39-87BFA550E13A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{541572F4-E051-F4F8-9B39-87BFA550E13A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{541572F4-E051-F4F8-9B39-87BFA550E13A}.Release|Any CPU.Build.0 = Release|Any CPU
{59C211A4-B928-7505-AF2E-6C604DAB3622}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{59C211A4-B928-7505-AF2E-6C604DAB3622}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59C211A4-B928-7505-AF2E-6C604DAB3622}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59C211A4-B928-7505-AF2E-6C604DAB3622}.Release|Any CPU.Build.0 = Release|Any CPU
{A5C76622-FE9B-BD41-A430-5208CCE95FDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5C76622-FE9B-BD41-A430-5208CCE95FDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5C76622-FE9B-BD41-A430-5208CCE95FDA}.Release|Any CPU.ActiveCfg = Release|Any CPU