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 audioFiles = new List(); 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? val) ? val : new List(); 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()); } /// /// 切换音乐 /// /// private void waveOutEvent_Provider(Wave16ToFloatProvider wave16ToFloatProvider) { songOutputDevice.Stop(); songOutputDevice.Dispose(); songOutputDevice = new WaveOutEvent(); songOutputDevice.Init(wave16ToFloatProvider); songOutputDevice.PlaybackStopped += OnPlaybackStopped; } /// /// 调整音乐音量 /// /// 音量大小 1-100 public void volume_change(int val)=> audio_File_Processor.volume_change(val); public List 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(); } } }