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
end end
audio.beep(1000, 0.4, 0.2) audio.beep(1000, 0.4, 0.2, "square")
if shouldInstallOS() then if shouldInstallOS() then
installOS() installOS()

View file

@ -4,6 +4,7 @@ using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -14,8 +15,11 @@ public class Audio : IDisposable
public const int SampleRate = 48000; public const int SampleRate = 48000;
public const AudioChannels Channels = AudioChannels.Mono; public const AudioChannels Channels = AudioChannels.Mono;
public readonly DynamicSoundEffectInstance Sound; public readonly DynamicSoundEffectInstance Sound;
private static readonly Random rng = new();
public Audio() public Audio()
{ {
GenerateSawtoothWave(440, 1);
Sound = new DynamicSoundEffectInstance(SampleRate, Channels); Sound = new DynamicSoundEffectInstance(SampleRate, Channels);
} }
@ -59,6 +63,56 @@ public class Audio : IDisposable
return buffer; 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() public void Dispose()
{ {
GC.SuppressFinalize(this); GC.SuppressFinalize(this);

View file

@ -139,15 +139,31 @@ public class Audio : IPlugin
{ {
var L = Lua.FromIntPtr(state); var L = Lua.FromIntPtr(state);
var freq = L.CheckNumber(1); var freq = L.OptNumber(1, 440);
var time = L.OptNumber(2, 1); var time = L.OptNumber(2, 1);
var volume = L.OptNumber(3, 1); var volume = L.OptNumber(3, 1);
volume = Math.Clamp(volume, 0, 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 try
{ {