From 574b85ceb082eafc24b1e1d10123949eae40d126 Mon Sep 17 00:00:00 2001 From: CreepyCrafter24 <33260128+CreepyCrafter24@users.noreply.github.com> Date: Tue, 17 Mar 2020 15:08:52 +0100 Subject: [PATCH] Fix beeper, slightly broken (unexpected console output on linux) --- testexetrisathlon/Program.cs | 9 ++-- testexetrisathlon/SoundManagement/Beeper.cs | 47 ++++++++++++++++++- .../SoundManagement/LinuxSoundManager.cs | 37 +++++++++------ .../SoundManagement/ProcessLoop.cs | 33 ------------- testexetrisathlon/testexetrisathlon.csproj | 1 + 5 files changed, 72 insertions(+), 55 deletions(-) delete mode 100644 testexetrisathlon/SoundManagement/ProcessLoop.cs diff --git a/testexetrisathlon/Program.cs b/testexetrisathlon/Program.cs index 1f0d99f..f89ddee 100644 --- a/testexetrisathlon/Program.cs +++ b/testexetrisathlon/Program.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; +using System.Threading; using testexetrisathlon.SoundManagement; using static System.Console; @@ -79,7 +80,6 @@ namespace testexetrisathlon SetWindowSize(50, 40); } SetCursorPosition(0, 0); - Clear(); bool playing = true; GameState state = GameState.Menu; try @@ -185,6 +185,7 @@ namespace testexetrisathlon ForegroundColor = Colors[1]; SetCursorPosition(0, 0); Clear(); + Beeper.Dispose(); } private static void DrawSymbol() @@ -212,11 +213,6 @@ namespace testexetrisathlon { Clear(); DrawSymbol(); - if (!OSCheck.IsWindows) - { - SetCursorPosition(2, 19); - Write("Volume is not supported in this build!"); - } bool barActive = true; int currentSetting = 0; while (barActive) @@ -380,6 +376,7 @@ namespace testexetrisathlon WriteLine("Score " + _score + "/" + (Math.Pow(_level, 2) * 100)); SetCursorPosition(25, 2); WriteLine("LinesCleared " + _linesCleared); + DrawBorder(); } public static void DrawBorder() diff --git a/testexetrisathlon/SoundManagement/Beeper.cs b/testexetrisathlon/SoundManagement/Beeper.cs index ba5804f..3235b5b 100644 --- a/testexetrisathlon/SoundManagement/Beeper.cs +++ b/testexetrisathlon/SoundManagement/Beeper.cs @@ -1,15 +1,60 @@ using System; +using System.Collections.Generic; +using System.IO; +using Bassoon; namespace testexetrisathlon.SoundManagement { public static class Beeper { + private static readonly Dictionary, Tuple> Beeps = new Dictionary, Tuple>(); public static void Beep(int frequency, int duration) { if (OSCheck.IsWindows) Console.Beep(frequency, duration); else - Console.Write("\a"); + { + Tuple key = new Tuple(frequency, duration); + if (!Beeps.ContainsKey(key)) + { + string file = Path.GetTempFileName(); + File.Move(file, Path.ChangeExtension(file, "wav")); + file = Path.ChangeExtension(file, "wav"); + File.WriteAllBytes(file, BeepBeep(1000, frequency, duration)); + Beeps.Add(key, new Tuple(file, new Sound(file))); + } + Beeps[key].Item2.Cursor = 0; + Beeps[key].Item2.Play(); + Console.Clear(); + } + } + + private static byte[] BeepBeep(int amplitude, int frequency, int duration) + { + double a = ((amplitude * Math.Pow(2, 15)) / 1000) - 1; + double deltaFt = (2 * Math.PI * frequency) / 44100.0; + + int samples = (441 * duration) / 10; + int bytes = samples * 4; + int[] hdr = {0X46464952, 36 + bytes, 0X45564157, 0X20746D66, 16, 0X20001, 44100, 176400, 0X100004, 0X61746164, bytes}; + using MemoryStream ms = new MemoryStream(44 + bytes); + using BinaryWriter bw = new BinaryWriter(ms); + for (int I = 0; I < hdr.Length; I++) bw.Write(hdr[I]); + for (int T = 0; T < samples; T++) + { + short sample = Convert.ToInt16(a * Math.Sin(deltaFt * T)); + bw.Write(sample); + bw.Write(sample); + } + bw.Flush(); + ms.Seek(0, SeekOrigin.Begin); + return ms.ToArray(); + } + + public static void Dispose() + { + if (OSCheck.IsWindows) + foreach (Tuple file in Beeps.Values) File.Delete(file.Item1); } } } \ No newline at end of file diff --git a/testexetrisathlon/SoundManagement/LinuxSoundManager.cs b/testexetrisathlon/SoundManagement/LinuxSoundManager.cs index 9ac1fec..fa36508 100644 --- a/testexetrisathlon/SoundManagement/LinuxSoundManager.cs +++ b/testexetrisathlon/SoundManagement/LinuxSoundManager.cs @@ -1,26 +1,31 @@ +using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Reflection; +using Bassoon; namespace testexetrisathlon.SoundManagement { public class LinuxSoundManager : ISoundManager { - private static readonly Assembly Assembly = Assembly.GetExecutingAssembly(); - private ProcessLoop? _alsaProc; - private string _current; + private BassoonEngine _bassoon; + private Dictionary _loadedSounds; private Dictionary _files; - + private string _current; + private int _volume = 100; + private static readonly Assembly Assembly = Assembly.GetExecutingAssembly(); public void Dispose() { + foreach (Sound sound in _loadedSounds.Values) sound.Dispose(); + _bassoon.Dispose(); foreach (string file in _files.Values) File.Delete(file); - if (_alsaProc != null) _alsaProc.IsRunning = false; } public void Init(Dictionary manifestResources) { + _bassoon = new BassoonEngine(); _files = new Dictionary(); + _loadedSounds = new Dictionary(); foreach ((string name, string key) in manifestResources) { string file = Path.GetTempFileName(); @@ -31,26 +36,28 @@ namespace testexetrisathlon.SoundManagement resource.Seek(0, SeekOrigin.Begin); resource.CopyTo(fileStream); _files.Add(name, file); + _loadedSounds.Add(name, new Sound(file)); } + Console.Clear(); } public void SetCurrent(string id) { if (_current == id) return; - if (_alsaProc != null) _alsaProc.IsRunning = false; - _current = id; - //TODO fix actually killing, remove orphan processes - _alsaProc = new ProcessLoop(new ProcessStartInfo + if (!string.IsNullOrWhiteSpace(_current)) { - FileName = "aplay", - Arguments = $"-q {_files[id].Replace("\"", "\\\"")}", - CreateNoWindow = true - }); - _alsaProc.CreateLoopThread().Start(); + _loadedSounds[_current].Pause(); + _loadedSounds[_current].Cursor = 0; + } + _current = id; + _loadedSounds[_current].Play(); + Console.Clear(); } public void SetVolume(int percent) { + _volume = percent; + foreach (Sound sound in _loadedSounds.Values) sound.Volume = _volume / 100f; } } } \ No newline at end of file diff --git a/testexetrisathlon/SoundManagement/ProcessLoop.cs b/testexetrisathlon/SoundManagement/ProcessLoop.cs deleted file mode 100644 index 1a03af5..0000000 --- a/testexetrisathlon/SoundManagement/ProcessLoop.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Diagnostics; -using System.Threading; - -namespace testexetrisathlon.SoundManagement -{ - internal class ProcessLoop - { - private readonly ProcessStartInfo _info; - private Process _currentProc; - private bool _isRunning = true; - - public ProcessLoop(ProcessStartInfo info) => _info = info; - - public bool IsRunning - { - set - { - if (_isRunning && !value) - _currentProc.Kill(); - _isRunning = value; - } - } - - public Thread CreateLoopThread() => new Thread(() => - { - while (_isRunning) - { - _currentProc = Process.Start(_info); - _currentProc.WaitForExit(); - } - }); - } -} \ No newline at end of file diff --git a/testexetrisathlon/testexetrisathlon.csproj b/testexetrisathlon/testexetrisathlon.csproj index cc5343d..b7473dc 100644 --- a/testexetrisathlon/testexetrisathlon.csproj +++ b/testexetrisathlon/testexetrisathlon.csproj @@ -28,6 +28,7 @@ + \ No newline at end of file