165 lines
6.0 KiB
C#
165 lines
6.0 KiB
C#
|
using NAudio.Wave;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Reflection;
|
|||
|
using System.Resources;
|
|||
|
using System.Text;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using CDSAE3_Lian_Lian_Kan.Properties;
|
|||
|
using NAudio.Wave.SampleProviders;
|
|||
|
namespace CDSAE3_Lian_Lian_Kan.Sound
|
|||
|
{
|
|||
|
public class Audio_processer
|
|||
|
{
|
|||
|
class Audio_File_Processor
|
|||
|
{
|
|||
|
private WaveChannel32? volumeStream;
|
|||
|
private List<string> audioFiles = new List<string>();
|
|||
|
string base_path;
|
|||
|
int next_song = 0;
|
|||
|
int volume = 90;
|
|||
|
public Audio_File_Processor()
|
|||
|
{
|
|||
|
base_path = AppDomain.CurrentDomain.BaseDirectory;
|
|||
|
}
|
|||
|
internal void set_Albums(string s)=>audioFiles = Settings.musics.TryGetValue(s, out List<string>? val) ? val : new List<string>();
|
|||
|
internal Wave16ToFloatProvider get_next_song()
|
|||
|
{
|
|||
|
volumeStream?.Close();
|
|||
|
string name = audioFiles[next_song];
|
|||
|
next_song++;
|
|||
|
next_song %= audioFiles.Count;
|
|||
|
name = name.Split('.').First().Replace(" ","_").Replace("-","_");
|
|||
|
object obj = Settings.res_Manager.GetObject(name, Settings.res_Culture)!;
|
|||
|
MemoryStream sound = new MemoryStream((byte[])obj);
|
|||
|
MemoryStream ms = new MemoryStream(StreamToBytes(sound));
|
|||
|
var ws = new Mp3FileReader(ms);
|
|||
|
BlockAlignReductionStream blockAlignReductionStream = new BlockAlignReductionStream(ws);
|
|||
|
Wave16ToFloatProvider wave16ToFloatProvider = new Wave16ToFloatProvider(blockAlignReductionStream);
|
|||
|
wave16ToFloatProvider.Volume = volume / 100f;
|
|||
|
return wave16ToFloatProvider;
|
|||
|
}
|
|||
|
internal Wave16ToFloatProvider get_last_song()
|
|||
|
{
|
|||
|
next_song = (next_song - 2 + audioFiles.Count) % audioFiles.Count;
|
|||
|
return get_next_song();
|
|||
|
}
|
|||
|
internal void volume_change(int val)
|
|||
|
{
|
|||
|
volume = val;
|
|||
|
if(volumeStream != null)
|
|||
|
volumeStream.Volume = volume / 100f;
|
|||
|
}
|
|||
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
~Audio_File_Processor()
|
|||
|
{
|
|||
|
volumeStream?.Close();
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
private WaveOutEvent songOutputDevice;
|
|||
|
private WaveOutEvent infoOutputDevice;
|
|||
|
Audio_File_Processor audio_File_Processor = new Audio_File_Processor();
|
|||
|
public Audio_processer()
|
|||
|
{
|
|||
|
songOutputDevice = new WaveOutEvent();
|
|||
|
infoOutputDevice = new WaveOutEvent();
|
|||
|
set_albums(get_albums().First());
|
|||
|
}
|
|||
|
private void OnPlaybackStopped(object? sender, StoppedEventArgs e)
|
|||
|
{
|
|||
|
next_song();
|
|||
|
resume_song();
|
|||
|
}
|
|||
|
public void pause_song()=>songOutputDevice.Pause();
|
|||
|
public void resume_song()=>songOutputDevice.Play();
|
|||
|
public void last_song()
|
|||
|
{
|
|||
|
waveOutEvent_Provider(audio_File_Processor.get_last_song());
|
|||
|
}
|
|||
|
public void next_song()
|
|||
|
{
|
|||
|
waveOutEvent_Provider(audio_File_Processor.get_next_song());
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 切换音乐
|
|||
|
/// </summary>
|
|||
|
/// <param name="waveChannel32"></param>
|
|||
|
private void waveOutEvent_Provider(Wave16ToFloatProvider wave16ToFloatProvider)
|
|||
|
{
|
|||
|
|
|||
|
songOutputDevice.Stop();
|
|||
|
songOutputDevice.Dispose();
|
|||
|
songOutputDevice = new WaveOutEvent();
|
|||
|
songOutputDevice.Init(wave16ToFloatProvider);
|
|||
|
songOutputDevice.PlaybackStopped += OnPlaybackStopped;
|
|||
|
}
|
|||
|
/// <summary>
|
|||
|
/// 调整音乐音量
|
|||
|
/// </summary>
|
|||
|
/// <param name="val">音量大小 1-100</param>
|
|||
|
public void volume_change(int val)=> audio_File_Processor.volume_change(val);
|
|||
|
public List<string> get_albums() => Settings.musics.Select(x => x.Key).ToList();
|
|||
|
public void set_albums(string s)
|
|||
|
{
|
|||
|
audio_File_Processor.set_Albums(s);
|
|||
|
}
|
|||
|
~Audio_processer()
|
|||
|
{
|
|||
|
songOutputDevice.Dispose();
|
|||
|
infoOutputDevice.Dispose();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|