Add support for other audio waveforms

This commit is contained in:
Alessandro Proto 2023-02-13 22:36:30 +01:00
parent d3bbedb30e
commit e24192fb26
3 changed files with 76 additions and 6 deletions

View file

@ -241,7 +241,7 @@ local function bootScreen()
end
end
audio.beep(1000, 0.4, 0.2)
audio.beep(1000, 0.4, 0.2, "square")
if shouldInstallOS() then
installOS()

View file

@ -4,6 +4,7 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
@ -14,8 +15,11 @@ public class Audio : IDisposable
public const int SampleRate = 48000;
public const AudioChannels Channels = AudioChannels.Mono;
public readonly DynamicSoundEffectInstance Sound;
private static readonly Random rng = new();
public Audio()
{
GenerateSawtoothWave(440, 1);
Sound = new DynamicSoundEffectInstance(SampleRate, Channels);
}
@ -59,6 +63,56 @@ public class Audio : IDisposable
return buffer;
}
public static byte[] GenerateTriangleWave(double frequency, double time, double volume = 1d)
{
var amplitude = 128 * volume;
var timeStep = 1d / SampleRate;
frequency /= 2;
var buffer = new byte[(int)(SampleRate * time)];
var ctime = 0d;
for (int i = 0; i < buffer.Length; i++)
{
var st = ctime * frequency - Math.Floor(ctime * frequency + 0.5);
var x = Math.Abs(st) * 2.0f - 1.0f;
buffer[i] = (byte)(amplitude * x);
ctime += timeStep;
}
return buffer;
}
public static byte[] GenerateSawtoothWave(double frequency, double time, double volume = 1d)
{
var amplitude = 128 * volume;
var timeStep = 1d / SampleRate;
frequency /= 2;
var buffer = new byte[(int)(SampleRate * time)];
var ctime = 0d;
for (int i = 0; i < buffer.Length; i++)
{
var x = ctime * frequency - Math.Floor(ctime * frequency + 0.5);
buffer[i] = (byte)(amplitude * x);
ctime += timeStep;
}
return buffer;
}
public static byte[] GenerateNoiseWave(double time, double volume = 1d)
{
var amplitude = 128 * volume;
var timeStep = 1d / SampleRate;
var buffer = new byte[(int)(SampleRate * time)];
var ctime = 0d;
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] = (byte)rng.Next(0, (int)amplitude);
ctime += timeStep;
}
return buffer;
}
public void Dispose()
{
GC.SuppressFinalize(this);

View file

@ -139,15 +139,31 @@ public class Audio : IPlugin
{
var L = Lua.FromIntPtr(state);
var freq = L.CheckNumber(1);
var freq = L.OptNumber(1, 440);
var time = L.OptNumber(2, 1);
var volume = L.OptNumber(3, 1);
volume = Math.Clamp(volume, 0, 1);
var buffer = Core.Audio.GenerateSquareWave(freq, time, volume);
var form = L.CheckOption(4, "sine", new string[]
{
"sine",
"square",
"triangle",
"sawtooth",
"noise",
null,
});
var buffer = form switch
{
0 => Core.Audio.GenerateSineWave(freq, time, volume),
1 => Core.Audio.GenerateSquareWave(freq, time, volume),
2 => Core.Audio.GenerateTriangleWave(freq, time, volume),
3 => Core.Audio.GenerateSawtoothWave(freq, time, volume),
4 => Core.Audio.GenerateNoiseWave(time, volume),
_ => throw new NotImplementedException()
};
try
{