diff --git a/audiotest/OpenTK.dll b/audiotest/OpenTK.dll new file mode 100644 index 0000000..c335751 --- /dev/null +++ b/audiotest/OpenTK.dll Binary files differ diff --git a/audiotest/OpenTK.dll.config b/audiotest/OpenTK.dll.config new file mode 100644 index 0000000..7098d39 --- /dev/null +++ b/audiotest/OpenTK.dll.config @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/audiotest/WavFile.cs b/audiotest/WavFile.cs new file mode 100644 index 0000000..0ac207b --- /dev/null +++ b/audiotest/WavFile.cs @@ -0,0 +1,64 @@ +using System; +using System.IO; +using System.Text; +using OpenTK.Audio.OpenAL; + +public class WavFile +{ + public byte[] Data; + public ALFormat Format; // Al.FORMAT_* + public int SampleRate; + + public static WavFile Load(string path) + { + using (var fs = File.OpenRead(path)) + using (var br = new BinaryReader(fs)) + { + if (new string(br.ReadChars(4)) != "RIFF") throw new Exception("Not RIFF: " + path); + br.ReadInt32(); + if (new string(br.ReadChars(4)) != "WAVE") throw new Exception("Not WAVE: " + path); + + short channels = 0, bits = 0; + int rate = 0; + byte[] data = null; + + while (fs.Position < fs.Length - 8) + { + string id = new string(br.ReadChars(4)); + int len = br.ReadInt32(); + + if (id == "fmt ") + { + br.ReadInt16(); // audio format (1 = PCM) + channels = br.ReadInt16(); + rate = br.ReadInt32(); + br.ReadInt32(); // byte rate + br.ReadInt16(); // block align + bits = br.ReadInt16(); + if (len > 16) br.ReadBytes(len - 16); + } + else if (id == "data") + { + data = br.ReadBytes(len); + } + else + { + br.ReadBytes(len); // skip unknown chunk + } + + if ((len & 1) == 1) br.ReadByte(); // chunks are word-aligned + } + + if (data == null) throw new Exception("No data chunk: " + path); + + ALFormat fmt; + if (channels == 1 && bits == 8) fmt = ALFormat.Mono8; + else if (channels == 1 && bits == 16) fmt = ALFormat.Mono16; + else if (channels == 2 && bits == 8) fmt = ALFormat.Stereo8; + else if (channels == 2 && bits == 16) fmt = ALFormat.Stereo16; + else throw new Exception("Unsupported WAV: " + channels + "ch " + bits + "bit"); + + return new WavFile { Data = data, Format = fmt, SampleRate = rate }; + } + } +} \ No newline at end of file diff --git a/audiotest/alsoft.conf b/audiotest/alsoft.conf new file mode 100644 index 0000000..fdbb03b --- /dev/null +++ b/audiotest/alsoft.conf @@ -0,0 +1,6 @@ +[general] +drivers = pulse,alsa +resampler = bsinc24 +period_size = 1024 +periods = 4 +output-limiter = true \ No newline at end of file diff --git a/audiotest/altest.cs b/audiotest/altest.cs new file mode 100644 index 0000000..8b812af --- /dev/null +++ b/audiotest/altest.cs @@ -0,0 +1,42 @@ +using System; +using System.Threading; +using OpenTK.Audio; +using OpenTK.Audio.OpenAL; + +class AlTest +{ + static void Main(string[] args) + { + if (args.Length < 1) + { + Console.WriteLine("usage: altest [gain 0..1]"); + return; + } + float gain = args.Length > 1 ? float.Parse(args[1]) : 1.0f; + + var ctx = new AudioContext(); + ctx.MakeCurrent(); + Console.WriteLine("device: " + AudioContext.CurrentContext.CurrentDevice); + + WavFile w = WavFile.Load(args[0]); + Console.WriteLine("{0} {1} Hz {2} bytes", w.Format, w.SampleRate, w.Data.Length); + + int buf = AL.GenBuffer(); + AL.BufferData(buf, w.Format, w.Data, w.Data.Length, w.SampleRate); + + int src = AL.GenSource(); + AL.Source(src, ALSourcei.Buffer, buf); + AL.Source(src, ALSourcef.Gain, gain); + AL.SourcePlay(src); + + ALError e = AL.GetError(); + if (e != ALError.NoError) Console.WriteLine("AL error: " + AL.GetErrorString(e)); + + while (AL.GetSourceState(src) == ALSourceState.Playing) + Thread.Sleep(50); + + AL.DeleteSource(src); + AL.DeleteBuffer(buf); + ctx.Dispose(); + } +} \ No newline at end of file diff --git a/audiotest/altest.exe b/audiotest/altest.exe new file mode 100644 index 0000000..283c6d2 --- /dev/null +++ b/audiotest/altest.exe Binary files differ diff --git a/audiotest/build.sh b/audiotest/build.sh new file mode 100644 index 0000000..e734470 --- /dev/null +++ b/audiotest/build.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -e +cd "$(dirname "$0")/.." + +OUT=audiotest +rm -rf "$OUT" +mkdir -p "$OUT/src" "$OUT/sound" + +cp altest.cs WavFile.cs "$OUT/src/" +cp OpenTK.dll OpenTK.dll.config "$OUT/" +cp bin/linux/sound/SND200.wav "$OUT/sound/" +cp audiotest_files/{install.sh,run.sh,alsoft.conf} "$OUT/" + +mcs "$OUT/src/altest.cs" "$OUT/src/WavFile.cs" \ + -r:"$OUT/OpenTK.dll" -out:"$OUT/altest.exe" + +chmod +x "$OUT"/*.sh +tar czf audiotest.tar.gz "$OUT" +echo "built audiotest.tar.gz" \ No newline at end of file diff --git a/audiotest/readme.md b/audiotest/readme.md new file mode 100644 index 0000000..923cf84 --- /dev/null +++ b/audiotest/readme.md @@ -0,0 +1,3 @@ +sudo apt install mono-runtime libmono-system-drawing4.0-cil libopenal1 pulseaudio-utils sox +paplay sound/SND200.wav +mono ./altest.exe sound/SND200.wav \ No newline at end of file