-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* develop: Adding silence calculator utility. Asserting how silence maps in the hash domain.
- Loading branch information
Showing
9 changed files
with
111 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
src/SoundFingerprinting.Tests/Unit/Utils/SilenceCalculatorTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
namespace SoundFingerprinting.Tests.Unit.Utils; | ||
|
||
using System.Linq; | ||
using NUnit.Framework; | ||
using SoundFingerprinting.Data; | ||
using SoundFingerprinting.Utils; | ||
|
||
[TestFixture] | ||
public class SilenceCalculatorTest | ||
{ | ||
[Test] | ||
public void ShouldCalculateCorrectly() | ||
{ | ||
var hashedFingerprints = Enumerable.Range(0, 10).Select(index => | ||
{ | ||
int[] hashBins = index % 2 == 0 ? Enumerable.Repeat(-1, 25).ToArray() : Enumerable.Repeat(1, 25).ToArray(); | ||
return new HashedFingerprint(hashBins, (uint)index, (float)index / 2, []); | ||
}).ToArray(); | ||
|
||
var hashes = new Hashes(hashedFingerprints, 10, MediaType.Audio); | ||
|
||
var timespan = SilenceCalculator.Calculate(hashes); | ||
|
||
Assert.That(timespan.TotalSeconds, Is.EqualTo(2.5).Within(0.1)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
namespace SoundFingerprinting.Utils; | ||
|
||
using System; | ||
using System.Linq; | ||
using SoundFingerprinting.Data; | ||
|
||
/// <summary> | ||
/// Silence calculator. | ||
/// </summary> | ||
/// <remarks> | ||
/// A utility class allowing to calculate silence contained within audio and video hashes. <br /> | ||
/// It only makes sense to calculate silence for hashes if TreatAsSilence flag is set to true during fingerprinting. <br /> | ||
/// Do not set the flag to true unless you've explicitly arrived to the conclusion you need it. | ||
/// </remarks> | ||
public static class SilenceCalculator | ||
{ | ||
/// <summary> | ||
/// Silence value, derived from the fact that an array of [255, 255, 255, 255] min hashes will map to -1 during hashes conversion. | ||
/// </summary> | ||
private const int Silence = -1; | ||
|
||
/// <summary> | ||
/// Calculate silence contained within audio and video hashes. | ||
/// </summary> | ||
/// <param name="avHashes">AVHashes to analyze.</param> | ||
/// <returns> | ||
/// Tuple containing audio and video silence. For video hashes silence means black frames. | ||
/// </returns> | ||
public static (TimeSpan, TimeSpan) Calculate(AVHashes avHashes) | ||
{ | ||
var audioSilence = Calculate(avHashes.Audio); | ||
var videoSilence = Calculate(avHashes.Video); | ||
return (audioSilence, videoSilence); | ||
} | ||
|
||
/// <summary> | ||
/// Calculate contained silence within hashes. | ||
/// </summary> | ||
/// <param name="hashes">Hashes to analyze.</param> | ||
/// <returns>Timespan.</returns> | ||
/// <remarks> | ||
/// It only makes sense to calculate silence for hashes if TreatAsSilence flag is set to true during fingerprinting. | ||
/// </remarks> | ||
public static TimeSpan Calculate(Hashes? hashes) | ||
{ | ||
if (hashes == null || hashes.IsEmpty) | ||
{ | ||
return TimeSpan.Zero; | ||
} | ||
|
||
var items = hashes.OrderBy(_ => _.SequenceNumber).ToArray(); | ||
double silence = 0; | ||
for (int i = 1; i < items.Length; i++) | ||
{ | ||
if (hashes[i - 1].HashBins.All(_ => _ == Silence)) | ||
{ | ||
silence += items[i].StartsAt - items[i - 1].StartsAt; | ||
} | ||
} | ||
|
||
return TimeSpan.FromSeconds(silence); | ||
} | ||
} |