This repository has been archived on 2024-06-21. You can view files and clone it, but cannot push or open issues or pull requests.
CDSAE3/CDSAE3_Lian_Lian_Kan/Sound/AudioPlayer.cs

143 lines
5.1 KiB
C#
Raw Normal View History

2024-04-02 13:57:04 +00:00
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace CDSAE3_Lian_Lian_Kan.Sound
{
internal class AudioPlayer : IDisposable
{
2024-04-08 13:04:47 +00:00
readonly byte[] source_obj;
readonly MemoryStream sound;
readonly MemoryStream ms;
readonly Mp3FileReader ws;
readonly BlockAlignReductionStream blockAlignReductionStream;
readonly Wave16ToFloatProvider wave16ToFloatProvider;
readonly WaveOutEvent waveOutEvent;
readonly Action<string,AudioPlayer>? finished;
readonly string file_name;
bool shuting_down = false;
2024-04-02 13:57:04 +00:00
internal int volume { get; set; }
internal AudioPlayer(string file_name, int volume)
{
this.file_name = file_name;
this.volume = volume;
file_name = file_name.Split('.').First().Replace(" ", "_").Replace("-", "_");
2024-04-08 13:04:47 +00:00
source_obj = Etcs.audio_Res_Manager.Get_Audio_Resources(file_name);
sound = new MemoryStream(source_obj);
2024-04-02 13:57:04 +00:00
ms = new MemoryStream(StreamToBytes(sound));
ws = new Mp3FileReader(ms);
2024-04-19 02:00:37 +00:00
2024-04-02 13:57:04 +00:00
blockAlignReductionStream = new BlockAlignReductionStream(ws);
2024-04-19 02:00:37 +00:00
2024-04-02 13:57:04 +00:00
wave16ToFloatProvider = new Wave16ToFloatProvider(blockAlignReductionStream);
2024-04-19 02:00:37 +00:00
2024-04-02 13:57:04 +00:00
wave16ToFloatProvider.Volume = volume / 100f;
waveOutEvent = new WaveOutEvent();
waveOutEvent.Init(wave16ToFloatProvider);
waveOutEvent.PlaybackStopped += WaveOutEvent_PlaybackStopped;
}
internal AudioPlayer(string file_name, int volume, Action<string,AudioPlayer> finished)
{
this.file_name = file_name;
this.volume = volume;
this.finished = finished;
2024-04-18 00:38:59 +00:00
file_name = file_name.Split('.').First().Replace(" ", "_").Replace("-", "_").Replace(",","_");
2024-04-08 13:04:47 +00:00
source_obj = Etcs.audio_Res_Manager.Get_Audio_Resources(file_name);
sound = new MemoryStream(source_obj);
2024-04-02 13:57:04 +00:00
ms = new MemoryStream(StreamToBytes(sound));
ws = new Mp3FileReader(ms);
blockAlignReductionStream = new BlockAlignReductionStream(ws);
wave16ToFloatProvider = new Wave16ToFloatProvider(blockAlignReductionStream);
wave16ToFloatProvider.Volume = volume / 100f;
waveOutEvent = new WaveOutEvent();
waveOutEvent.Init(wave16ToFloatProvider);
waveOutEvent.PlaybackStopped += WaveOutEvent_PlaybackStopped;
}
public void volume_change(int val)
{
volume = val;
wave16ToFloatProvider.Volume = volume / 100f;
}
public void pause_song() => waveOutEvent.Pause();
public void resume_song() => waveOutEvent.Play();
private void WaveOutEvent_PlaybackStopped(object? sender, StoppedEventArgs e)
{
2024-04-08 13:04:47 +00:00
if(shuting_down) return;
2024-04-02 13:57:04 +00:00
finished?.Invoke(file_name,this);
Dispose();
}
public void Dispose()
{
2024-04-08 13:04:47 +00:00
shuting_down = true;
2024-04-02 13:57:04 +00:00
waveOutEvent.Stop();
sound.Dispose();
ms.Dispose();
2024-04-19 02:00:37 +00:00
try
{
ws.Dispose();
}catch(Exception)
{ }
2024-04-08 13:04:47 +00:00
blockAlignReductionStream.Dispose();
2024-04-02 13:57:04 +00:00
waveOutEvent.Dispose();
2024-04-08 13:04:47 +00:00
GC.SuppressFinalize(this);
2024-04-02 13:57:04 +00:00
}
internal static byte[] StreamToBytes(Stream stream)
{
long originalPosition = 0;
if (stream.CanSeek)
{
originalPosition = stream.Position;
stream.Position = 0;
}
try
{
byte[] readBuffer = new byte[4096];
int totalBytesRead = 0;
int bytesRead;
while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
{
totalBytesRead += bytesRead;
if (totalBytesRead == readBuffer.Length)
{
int nextByte = stream.ReadByte();
if (nextByte != -1)
{
byte[] temp = new byte[readBuffer.Length * 2];
Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
readBuffer = temp;
totalBytesRead++;
}
}
}
byte[] buffer = readBuffer;
if (readBuffer.Length != totalBytesRead)
{
buffer = new byte[totalBytesRead];
Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
}
return buffer;
}
finally
{
if (stream.CanSeek)
{
stream.Position = originalPosition;
}
}
}
}
}