Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a line per channel on spectral density graph #265

Merged
merged 10 commits into from
Jan 30, 2025
Prev Previous commit
Cleanup and add a TODO to track down
Signed-off-by: Dave Thaler <[email protected]>
dthaler committed Jan 29, 2025

Verified

This commit was signed with the committer’s verified signature.
igorkulman Igor Kulman
commit 46ded5282100d22477d31d11c6323fe7d98dee02
25 changes: 22 additions & 3 deletions OrcanodeMonitor/Core/FrequencyInfo.cs
Original file line number Diff line number Diff line change
@@ -32,6 +32,16 @@ public FrequencyInfo(float[] data, int sampleRate, int channels, OrcanodeOnlineS

private void ComputeFrequencyMagnitudes(float[] data, int sampleRate, int channelCount)
{
if (data == null || data.Length == 0)
throw new ArgumentException("Audio data cannot be null or empty", nameof(data));
#if false
// TODO: there seems to be some issue here to track down.
if (data.Length % channelCount != 0)
throw new ArgumentException("Data length must be divisible by channel count", nameof(data));
#endif
if (sampleRate <= 0)
throw new ArgumentException("Sample rate must be positive", nameof(sampleRate));

int n = data.Length / channelCount;

// Create an array of complex data for each channel.
@@ -54,7 +64,7 @@ private void ComputeFrequencyMagnitudes(float[] data, int sampleRate, int channe
for (int ch = 0; ch < channelCount; ch++)
{
Fourier.Forward(complexData[ch], FourierOptions.Matlab);
FrequencyMagnitudesForChannel[ch] = new Dictionary<double, double>();
FrequencyMagnitudesForChannel[ch] = new Dictionary<double, double>(n / 2);
for (int i = 0; i < n / 2; i++)
{
double magnitude = complexData[ch][i].Magnitude;
@@ -139,10 +149,19 @@ public Dictionary<double, double> GetFrequencyMagnitudes(int? channel = null)
public double GetMaxMagnitude(int? channel = null) => GetFrequencyMagnitudes(channel).Values.Max();

/// <summary>
/// Compute the sound-to-hum ratio.
/// Compute the ratio between non-hum and hum frequencies in the audio signal.
/// This ratio helps determine if the signal is intelligible or just noise.
/// </summary>
/// <param name="channel">Channel number, or null for an aggregate</param>
/// <returns>Ratio</returns>
/// <returns>
/// The ratio of non-hum to hum frequencies. A higher ratio indicates a clearer signal.
/// Returns 0 when no hum is detected to avoid division by zero.
/// </returns>
/// <remarks>
/// The ratio is calculated by dividing the total magnitude of non-hum frequencies
/// by the total magnitude of hum frequencies (50Hz and 60Hz bands).
/// A minimum value of 1 is used for hum magnitude to prevent division by zero.
/// </remarks>
public double GetSignalRatio(int? channel = null)
{
double hum = Math.Max(GetTotalHumMagnitude(channel), 1);