88 lines
2.5 KiB
C#
88 lines
2.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Godot;
|
|
using NAudio.Wave;
|
|
|
|
namespace AudioEditor;
|
|
|
|
public partial class AudioFileAnalyzer : Node
|
|
{
|
|
public static AudioFileAnalyzer Instance { get; private set; }
|
|
|
|
public override void _Ready()
|
|
{
|
|
base._Ready();
|
|
Instance = this;
|
|
}
|
|
|
|
public void AnalyzeFile(string path, out WaveformInfo waveformInfo)
|
|
{
|
|
waveformInfo = new();
|
|
|
|
if (_waveformInfoCache.ContainsKey(path))
|
|
{
|
|
waveformInfo = _waveformInfoCache[path];
|
|
return;
|
|
}
|
|
|
|
var ext = Path.GetExtension(path);
|
|
|
|
switch (ext)
|
|
{
|
|
case ".wav":
|
|
GD.Print("Analyzing a WAV file...");
|
|
AnalyzeWav(path, out waveformInfo);
|
|
break;
|
|
default:
|
|
GD.Print($"Format {ext} is not supported!");
|
|
break;
|
|
}
|
|
|
|
_waveformInfoCache.Add(path, waveformInfo);
|
|
}
|
|
|
|
public bool TryGetFromCache(string path, out WaveformInfo waveformInfo)
|
|
{
|
|
return _waveformInfoCache.TryGetValue(path, out waveformInfo);
|
|
}
|
|
|
|
private void AnalyzeWav(string path, out WaveformInfo waveformInfo)
|
|
{
|
|
waveformInfo = new WaveformInfo();
|
|
using (var reader = new WaveFileReader(path))
|
|
{
|
|
waveformInfo.Length = reader.TotalTime;
|
|
waveformInfo.SampleRate = reader.WaveFormat.SampleRate;
|
|
|
|
long sampleCount = reader.Length / reader.WaveFormat.BlockAlign;
|
|
waveformInfo.Samples = new float[sampleCount];
|
|
|
|
// Render the waveform
|
|
byte[] buffer = new byte[reader.WaveFormat.BlockAlign];
|
|
for (int i = 0; i < sampleCount; i++)
|
|
{
|
|
int sampleIndex = i * reader.WaveFormat.BlockAlign;
|
|
while (reader.Position < reader.Length)
|
|
{
|
|
// Read the raw bytes for the current sample
|
|
reader.Read(buffer, 0, buffer.Length);
|
|
|
|
// Convert the byte array to a 16-bit sample
|
|
short sample = BitConverter.ToInt16(buffer, 0);
|
|
|
|
waveformInfo.Samples[sampleIndex++] = (float)sample / short.MaxValue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private Dictionary<string, WaveformInfo> _waveformInfoCache = new();
|
|
}
|
|
|
|
public class WaveformInfo
|
|
{
|
|
public int SampleRate { get; set; }
|
|
public TimeSpan Length { get; set; }
|
|
public float[] Samples { get; set; }
|
|
} |