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

142 lines
4.9 KiB
C#

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
{
object source_obj;
MemoryStream sound;
MemoryStream ms;
Mp3FileReader ws;
BlockAlignReductionStream blockAlignReductionStream;
Wave16ToFloatProvider wave16ToFloatProvider;
WaveOutEvent waveOutEvent;
Action<string,AudioPlayer>? finished;
string file_name;
bool shutdown = false;
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("-", "_");
source_obj = Etcs.res_Manager.GetObject(file_name, Etcs.res_Culture)!;
sound = new MemoryStream((byte[])source_obj);
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;
}
internal AudioPlayer(string file_name, int volume, Action<string,AudioPlayer> finished)
{
this.file_name = file_name;
this.volume = volume;
this.finished = finished;
file_name = file_name.Split('.').First().Replace(" ", "_").Replace("-", "_");
source_obj = Etcs.res_Manager.GetObject(file_name, Etcs.res_Culture)!;
sound = new MemoryStream((byte[])source_obj);
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)
{
if(shutdown) return;
finished?.Invoke(file_name,this);
Dispose();
}
~AudioPlayer()
{
Dispose();
}
public void Dispose()
{
shutdown = true;
waveOutEvent.Stop();
sound.Dispose();
ms.Dispose();
//ws.Dispose();
//blockAlignReductionStream.Dispose();
waveOutEvent.Dispose();
}
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;
}
}
}
}
}