Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion Prowl.Editor/Assets/Importers/AudioClipImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
using Prowl.Runtime.Audio;
using Prowl.Runtime.GUI;
using Prowl.Runtime.Utils;
using NVorbis;

namespace Prowl.Editor.Assets.Importers;

[Importer("FileIcon.png", typeof(AudioClip), ".wav")]
[Importer("FileIcon.png", typeof(AudioClip), ".wav", ".wave", ".ogg")]
public class AudioClipImporter : ScriptedImporter
{
public override void Import(SerializedAsset ctx, FileInfo assetPath)
Expand All @@ -20,10 +21,55 @@ public override void Import(SerializedAsset ctx, FileInfo assetPath)
{
".wav" => LoadWav(assetPath),
".wave" => LoadWav(assetPath),
".ogg" => LoadOgg(assetPath),
".oga" => LoadOgg(assetPath),
_ => throw new InvalidOperationException("Unsupported audio format: " + assetPath.Extension.ToLower()),
});
}

private static AudioClip LoadOgg(FileInfo file)
{
// Decode Ogg Vorbis to interleaved 16-bit PCM (little-endian) using NVorbis
using var fs = file.OpenRead();
using var vorbis = new VorbisReader(fs, false);

int channels = vorbis.Channels;
int sampleRate = vorbis.SampleRate;
const short bitsPerSample = 16; // output s16 PCM

// Converting NVorbis outputs floats of [-1..1] interleaved across channels
// to s16 to avoid large allocations.
var floatBuf = new float[4096]; // count is "samples"
using var ms = new MemoryStream();

int samplesRead;
Span<byte> le = stackalloc byte[2]; // scratch for one s16

while ((samplesRead = vorbis.ReadSamples(floatBuf, 0, floatBuf.Length)) > 0)
{
for (int i = 0; i < samplesRead; i++)
{
// clamp and convert float -> 16-bit signed
float f = floatBuf[i];
if (f > 1f) f = 1f;
else if (f < -1f) f = -1f;

short s = (short)MathF.Round(f * 32767f);

// write little-endian
System.Buffers.Binary.BinaryPrimitives.WriteInt16LittleEndian(le, s);
ms.Write(le);
}
}

byte[] audioData = ms.ToArray();

// Creating the clip just like the WAV path does:
AudioClip audioClip = AudioClip.Create(file.Name, audioData, (short)channels, bitsPerSample, sampleRate);
return audioClip;
}


#region Wave Format

private static AudioClip LoadWav(FileInfo file)
Expand Down
1 change: 1 addition & 0 deletions Prowl.Editor/Prowl.Editor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<PackageReference Include="AssimpNet" Version="5.0.0-beta1" />
<PackageReference Include="CommandLineParser" Version="2.9.1" />
<PackageReference Include="Glslang.NET" Version="1.2.0" />
<PackageReference Include="NVorbis" Version="0.10.5" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.9" />
<PackageReference Include="SixLabors.ImageSharp.Textures" Version="0.0.0-alpha.0.140" />
<PackageReference Include="SPIRV-Cross.NET" Version="1.0.1" />
Expand Down
1 change: 1 addition & 0 deletions Prowl.Players/Prowl.Desktop/Prowl.Desktop.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

<ItemGroup>
<!-- Janky fix to include native SDL2 binaries in the built player -->
<PackageReference Include="NVorbis" Version="0.10.5" />
<PackageReference Include="Ultz.Native.SDL" Version="2.30.1" />
</ItemGroup>
</Project>
1 change: 1 addition & 0 deletions Prowl.Runtime/Prowl.Runtime.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
<ItemGroup>
<!-- <PackageReference Include="Jitter2" Version="2.2.0" /> -->
<PackageReference Include="Jitter2.Double" Version="2.4.8-alpha" />
<PackageReference Include="NVorbis" Version="0.10.5" />
<PackageReference Include="Prowl.Echo" Version="1.7.0" />
<PackageReference Include="Silk.NET.OpenAL" Version="2.22.0" />
<PackageReference Include="Silk.NET.OpenAL.Soft.Native" Version="1.23.1" />
Expand Down