Fix beeper, slightly broken (unexpected console output on linux)

This commit is contained in:
CreepyCrafter24 2020-03-17 15:08:52 +01:00
parent fc043e0219
commit 574b85ceb0
5 changed files with 72 additions and 55 deletions

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading;
using testexetrisathlon.SoundManagement; using testexetrisathlon.SoundManagement;
using static System.Console; using static System.Console;
@ -79,7 +80,6 @@ namespace testexetrisathlon
SetWindowSize(50, 40); SetWindowSize(50, 40);
} }
SetCursorPosition(0, 0); SetCursorPosition(0, 0);
Clear();
bool playing = true; bool playing = true;
GameState state = GameState.Menu; GameState state = GameState.Menu;
try try
@ -185,6 +185,7 @@ namespace testexetrisathlon
ForegroundColor = Colors[1]; ForegroundColor = Colors[1];
SetCursorPosition(0, 0); SetCursorPosition(0, 0);
Clear(); Clear();
Beeper.Dispose();
} }
private static void DrawSymbol() private static void DrawSymbol()
@ -212,11 +213,6 @@ namespace testexetrisathlon
{ {
Clear(); Clear();
DrawSymbol(); DrawSymbol();
if (!OSCheck.IsWindows)
{
SetCursorPosition(2, 19);
Write("Volume is not supported in this build!");
}
bool barActive = true; bool barActive = true;
int currentSetting = 0; int currentSetting = 0;
while (barActive) while (barActive)
@ -380,6 +376,7 @@ namespace testexetrisathlon
WriteLine("Score " + _score + "/" + (Math.Pow(_level, 2) * 100)); WriteLine("Score " + _score + "/" + (Math.Pow(_level, 2) * 100));
SetCursorPosition(25, 2); SetCursorPosition(25, 2);
WriteLine("LinesCleared " + _linesCleared); WriteLine("LinesCleared " + _linesCleared);
DrawBorder();
} }
public static void DrawBorder() public static void DrawBorder()

View File

@ -1,15 +1,60 @@
using System; using System;
using System.Collections.Generic;
using System.IO;
using Bassoon;
namespace testexetrisathlon.SoundManagement namespace testexetrisathlon.SoundManagement
{ {
public static class Beeper public static class Beeper
{ {
private static readonly Dictionary<Tuple<int, int>, Tuple<string, Sound>> Beeps = new Dictionary<Tuple<int, int>, Tuple<string, Sound>>();
public static void Beep(int frequency, int duration) public static void Beep(int frequency, int duration)
{ {
if (OSCheck.IsWindows) if (OSCheck.IsWindows)
Console.Beep(frequency, duration); Console.Beep(frequency, duration);
else else
Console.Write("\a"); {
Tuple<int, int> key = new Tuple<int, int>(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<string, Sound>(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<string, Sound> file in Beeps.Values) File.Delete(file.Item1);
} }
} }
} }

View File

@ -1,26 +1,31 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using Bassoon;
namespace testexetrisathlon.SoundManagement namespace testexetrisathlon.SoundManagement
{ {
public class LinuxSoundManager : ISoundManager public class LinuxSoundManager : ISoundManager
{ {
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly(); private BassoonEngine _bassoon;
private ProcessLoop? _alsaProc; private Dictionary<string, Sound> _loadedSounds;
private string _current;
private Dictionary<string, string> _files; private Dictionary<string, string> _files;
private string _current;
private int _volume = 100;
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
public void Dispose() public void Dispose()
{ {
foreach (Sound sound in _loadedSounds.Values) sound.Dispose();
_bassoon.Dispose();
foreach (string file in _files.Values) File.Delete(file); foreach (string file in _files.Values) File.Delete(file);
if (_alsaProc != null) _alsaProc.IsRunning = false;
} }
public void Init(Dictionary<string, string> manifestResources) public void Init(Dictionary<string, string> manifestResources)
{ {
_bassoon = new BassoonEngine();
_files = new Dictionary<string, string>(); _files = new Dictionary<string, string>();
_loadedSounds = new Dictionary<string, Sound>();
foreach ((string name, string key) in manifestResources) foreach ((string name, string key) in manifestResources)
{ {
string file = Path.GetTempFileName(); string file = Path.GetTempFileName();
@ -31,26 +36,28 @@ namespace testexetrisathlon.SoundManagement
resource.Seek(0, SeekOrigin.Begin); resource.Seek(0, SeekOrigin.Begin);
resource.CopyTo(fileStream); resource.CopyTo(fileStream);
_files.Add(name, file); _files.Add(name, file);
_loadedSounds.Add(name, new Sound(file));
} }
Console.Clear();
} }
public void SetCurrent(string id) public void SetCurrent(string id)
{ {
if (_current == id) return; if (_current == id) return;
if (_alsaProc != null) _alsaProc.IsRunning = false; if (!string.IsNullOrWhiteSpace(_current))
_current = id;
//TODO fix actually killing, remove orphan processes
_alsaProc = new ProcessLoop(new ProcessStartInfo
{ {
FileName = "aplay", _loadedSounds[_current].Pause();
Arguments = $"-q {_files[id].Replace("\"", "\\\"")}", _loadedSounds[_current].Cursor = 0;
CreateNoWindow = true }
}); _current = id;
_alsaProc.CreateLoopThread().Start(); _loadedSounds[_current].Play();
Console.Clear();
} }
public void SetVolume(int percent) public void SetVolume(int percent)
{ {
_volume = percent;
foreach (Sound sound in _loadedSounds.Values) sound.Volume = _volume / 100f;
} }
} }
} }

View File

@ -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();
}
});
}
}

View File

@ -28,6 +28,7 @@
<Content Include="tetris_yUxH6t_256px.ico" /> <Content Include="tetris_yUxH6t_256px.ico" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Bassoon" Version="1.1.1" />
<PackageReference Include="NAudio" Version="1.10.0" /> <PackageReference Include="NAudio" Version="1.10.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>