{"id":22030882,"url":"https://github.com/addictedcs/soundfingerprinting","last_synced_at":"2026-10-19T17:21:36.561Z","repository":{"id":1871241,"uuid":"2796453","full_name":"AddictedCS/soundfingerprinting","owner":"AddictedCS","description":"Open source audio fingerprinting in .NET. An efficient algorithm for acoustic fingerprinting written purely in C#.  ","archived":false,"fork":false,"pushed_at":"2026-10-16T12:43:35.000Z","size":63993,"stargazers_count":1041,"open_issues_count":9,"forks_count":209,"subscribers_count":70,"default_branch":"develop","last_synced_at":"2026-10-17T00:35:27.272Z","etag":null,"topics":["acoustic-fingerprints","algorithm","audio","audio-processing","c-sharp","fingerprints","locality-sensitive-hashing","nearest-neighbor-search","recognition","shazam"],"latest_commit_sha":null,"homepage":"https://emysound.com","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"pinterest/PINCache","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AddictedCS.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null,"disclosure":null}},"created_at":"2011-11-17T15:36:24.000Z","updated_at":"2026-10-16T18:46:36.000Z","dependencies_parsed_at":"2023-02-12T17:30:47.755Z","dependency_job_id":"e5ba507b-fe0b-4c89-8efd-14607e48071e","html_url":"https://github.com/AddictedCS/soundfingerprinting","commit_stats":{"total_commits":1832,"total_committers":11,"mean_commits":"166.54545454545453","dds":"0.43231441048034935","last_synced_commit":"4f5f78b2ad161ecf585c61a59a03ce6612e5ad57"},"previous_names":[],"tags_count":140,"template":false,"template_full_name":null,"purl":"pkg:github/AddictedCS/soundfingerprinting","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AddictedCS%2Fsoundfingerprinting","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AddictedCS%2Fsoundfingerprinting/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AddictedCS%2Fsoundfingerprinting/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AddictedCS%2Fsoundfingerprinting/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AddictedCS","download_url":"https://codeload.github.com/AddictedCS/soundfingerprinting/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AddictedCS%2Fsoundfingerprinting/sbom","scorecard":{"id":8652,"data":{"date":"2025-08-11","repo":{"name":"github.com/AddictedCS/soundfingerprinting","commit":"9615068cc076915557fda7a42daf1d9ccb50729a"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.3,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/create-release.yml:1","Warn: no topLevel permission defined: .github/workflows/dotnetcore.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":5,"reason":"5 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/create-release.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/AddictedCS/soundfingerprinting/create-release.yml/develop?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/create-release.yml:53: update your workflow using https://app.stepsecurity.io/secureworkflow/AddictedCS/soundfingerprinting/create-release.yml/develop?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/create-release.yml:64: update your workflow using https://app.stepsecurity.io/secureworkflow/AddictedCS/soundfingerprinting/create-release.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/create-release.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/AddictedCS/soundfingerprinting/create-release.yml/develop?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/create-release.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/AddictedCS/soundfingerprinting/create-release.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/create-release.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/AddictedCS/soundfingerprinting/create-release.yml/develop?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/create-release.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/AddictedCS/soundfingerprinting/create-release.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/dotnetcore.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/AddictedCS/soundfingerprinting/dotnetcore.yml/develop?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/dotnetcore.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/AddictedCS/soundfingerprinting/dotnetcore.yml/develop?enable=pin","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   5 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: license.txt:0","Info: FSF or OSI recognized license: MIT License: license.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-14T14:06:23.227Z","repository_id":1871241,"created_at":"2025-08-14T14:06:23.227Z","updated_at":"2025-08-14T14:06:23.227Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":344872684,"owners_count":38332652,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-10-03T21:59:58.778Z","status":"online","status_checked_at":"2026-10-17T02:00:06.547Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["acoustic-fingerprints","algorithm","audio","audio-processing","c-sharp","fingerprints","locality-sensitive-hashing","nearest-neighbor-search","recognition","shazam"],"created_at":"2024-11-30T08:11:29.523Z","updated_at":"2026-10-19T17:21:36.555Z","avatar_url":"https://github.com/AddictedCS.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Audio/Video fingerprinting and recognition in .NET\n\n[![Join the chat at https://gitter.im/soundfingerprinting/Lobby](https://badges.gitter.im/soundfingerprinting/Lobby.svg)](https://gitter.im/soundfingerprinting/Lobby?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n![.NET Core](https://github.com/AddictedCS/soundfingerprinting/workflows/.NET%20Core/badge.svg)\n[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](license.txt)\n[![NuGet](https://img.shields.io/nuget/dt/SoundFingerprinting.svg)](https://www.nuget.org/packages/SoundFingerprinting)\n\n_soundfingerprinting_ is a C# framework designed for companies, enthusiasts, researchers in the fields of digital signal processing, data mining and audio/video recognition. It implements an efficient algorithm which provides fast insert and retrieval of acoustic and video fingerprints with high precision and recall rate.\n\n## Documentation\n\nFull documentation is available on the [Wiki][wiki-page] page.\n\nBelow code snippet shows how to extract acoustic fingerprints from an audio file and later use them as identifiers to recognize unknown audio query. These _fingerprints_ will be stored in a configurable datastore.\n\n```csharp\nprivate readonly IModelService modelService = new InMemoryModelService(); // store fingerprints in RAM\nprivate readonly IAudioService audioService = new SoundFingerprintingAudioService(); // default audio library\n\npublic async Task StoreForLaterRetrieval(string file)\n{\n    var track = new TrackInfo(\"GBBKS1200164\", \"Skyfall\", \"Adele\");\n\n    // create fingerprints\n    var avHashes = await FingerprintCommandBuilder.Instance\n                                .BuildFingerprintCommand()\n                                .From(file)\n                                .UsingServices(audioService)\n                                .Hash();\n\t\t\t\t\t\t\t\t\n    // store hashes in the database for later retrieval\n    await modelService.InsertAsync(track, avHashes);\n}\n```\n\n### Querying\nOnce you've inserted the fingerprints into the datastore, later you might want to query the storage in order to recognize the song those samples you have. The origin of query samples may vary: file, URL, microphone, radio tuner, etc. It's up to your application, where you get the samples from.\n\n```csharp\n\npublic async Task\u003cTrackData?\u003e GetBestMatchForSong(string file)\n{\n    int secondsToAnalyze = 10; // number of seconds to analyze from query file\n    int startAtSecond = 0; // start at the begining\n\t\n    // query the underlying database for similar audio sub-fingerprints\n    var queryResult = await QueryCommandBuilder.Instance.BuildQueryCommand()\n                                         .From(file, secondsToAnalyze, startAtSecond)\n                                         .UsingServices(modelService, audioService)\n                                         .Query();\n\n    return queryResult.BestMatch?.Audio.Track;\n}\n```\n\nIf the source was played with vinyl-style pitch control (tempo and pitch changed together) by a known percentage, pass it with the query samples to compensate before fingerprinting: `.From(audioSamples, sourcePlaybackSpeedPercentage: 8)`.\n\n### Fingerprints Storage\nThe default storage, which comes bundled with _soundfingerprinting_ NuGet package, is a plain in-memory storage, available via \u003ccode\u003eInMemoryModelService\u003c/code\u003e class. If you plan to use an external persistent storage for fingerprints **Emy** is the preferred choice. **Emy** provides a community version which is free for non-commercial use. More about **Emy** can be found [on wiki page][emy-wiki-page].\n\n### Supported audio/video formats\nRead [Supported Media Formats][audio-services-wiki-page] page for details about processing different file formats or realtime streams.\n\n### Video fingerprinting support since version 8.0.0\nSince `v8.0.0` video fingerprinting support has been added. Similarly to audio fingerprinting, video fingerprints are generated from video frames, and used to insert and later query the datastore for exact and similar matches. You can use `SoundFingerprinting` to fingerprint either audio or video content or both at the same time. More details about video fingerprinting are available [here][video-fingerprinting-wiki-page].\n\n### Spectral-profile path bridging since version 15.0.0\nSince `v15.0.0` an optional per-second spectral profile (SFM + relative power) can be captured at ingest and consumed at query time to bridge regions where hashes don't match across recordings — broadband intros (e.g. ocean waves), fade-outs, atmospheric silence. The mechanism is invisible by default; opt in per-query by setting `QueryConfiguration.SfmMatchStrategy` to one of the built-in strategies. The setter cascades through to `FingerprintConfiguration.ComputeSpectralProfile` so the profile is captured during query-time fingerprinting automatically.\n\n```csharp\nvar queryResult = await QueryCommandBuilder.Instance.BuildQueryCommand()\n    .From(file)\n    .WithQueryConfig(config =\u003e\n    {\n        // covers both broadband and silent regions in one pass\n        config.Audio.SfmMatchStrategy = CompositeBridgingStrategy.BroadbandOrSilent;\n        return config;\n    })\n    .UsingServices(modelService, audioService)\n    .Query();\n```\n\nAvailable strategies: `NoBridgingStrategy` (default — no change vs. v14), `BroadbandNoiseBridgingStrategy` (per-second SFM \u003e 0.70 on both sides), `SilentRegionBridgingStrategy` (per-second power \u003c 5% on both sides — replaces the removed `TreatSilenceAsSignal` flag), `SimilarProfileBridgingStrategy` (tight |Δsfm| \u003c 0.10 tolerance, capped to `min(10s, 0.30 × queryLength)` to keep speech-vs-speech merges safe), and `CompositeBridgingStrategy` for safe unions. Bridging is bounded by a universal 70% cumulative-bridged-seconds sanity cap and reported back via `Coverage.BridgedSeconds`. Synthetics are structurally indistinguishable from real matches downstream — no wire-format changes to `MatchedWith`. Tracks without a stored profile short-circuit cleanly to no-bridging (behavior identical to v14).\n\n### Asynchronous storage contract since version 16.0.0\nSince `v16.0.0` the storage contract is asynchronous and there is one interface family: `IQueryService` and `IModelService` expose `QueryEfficientlyAsync`, `ReadTracksByReferencesAsync`, `InsertAsync`, `ReadTrackByIdAsync`, `GetInfoAsync` and the other operations as `Task`-returning methods with a `CancellationToken`. Commands keep their names: `IQueryCommand.Query` and `IRealtimeQueryCommand.Query` were already `Task`-returning and now take a `CancellationToken`. `IAVQueryMatchRegistry.RegisterMatches` is `RegisterMatchesAsync`, and the realtime `SuccessCallback`, `DidNotPassFilterCallback` and `OngoingCallback` return a `Task` that the realtime command awaits before it consumes the next chunk. A remote storage awaits its network I/O; `InMemoryModelService` computes synchronously and returns completed tasks, so local behavior and snapshots are unchanged. Migration is mechanical: rename the call, `await` it, and return `Task.CompletedTask` from callbacks that do no I/O. The library never resumes on the caller's `SynchronizationContext`: every internal `await` is `ConfigureAwait(false)` and the realtime loop starts on the thread pool, so a UI application marshals callback results back to its own context.\n\n### Realtime seam jump policy since version 15.17.0\nA realtime query stitches consecutive chunks that match the same track into one result entry. When the track position jumps ahead of where the stream advance puts it, `RealtimeQueryConfiguration.SeamJumpPolicy` decides whether the chunk continues the same playing of the track (`Stitch`, the default), is a seek in the source (`SourceSkip`), or is another occurrence of audio that the track repeats (`NewOccurrenceAbove(seconds)`). Use the last one when stored tracks can contain the same audio several times, for example long programs that embed their advertising spots. Details, the reasoning and the measurements are on the [Realtime Seam Jump Policy][seam-jump-policy-wiki-page] wiki page.\n\n### Version Matrix\nIf you are using `FFmpegAudioService` as described in the [wiki][audio-services-wiki-page], follow the below version matrix.\n| SoundFingerprinting  | SoundFingerprinting.Emy | FFmpeg |\n| ---- | ------ |-----|\n| 8.x  | 8.x    | 4.x |\n| 9.x  | 9.x    | 5.x |\n| 10.x | 10.x   | 6.x |\n| 11.x | 11.x   | 6.x |\n| 12.x | 12.x   | 7.x |\n| 13.x | 13.x   | 7.x |\n| 14.x | 14.x   | 8.x |\n| 15.x | 15.x   | 8.x |\n\n\n\n### FAQ\n- Can I apply this algorithm for speech recognition purposes?\n\u003e No. The granularity of one fingerprint is roughly ~1.46 seconds.\n- Can the algorithm detect exact query position in resulted track?\n\u003e Yes.\n- Can I use **SoundFingerprinting** to detect ads in radio streams?\n\u003e Yes. Actually this is the most frequent use-case where SoundFingerprinting was successfully used.\n- How many tracks can I store in `InMemoryModelService`?\n\u003e 100 hours of content with `DefaultFingerprintingConfiguration` will consume ~5GB of RAM.\n\n### Get it on NuGet\n\n    Install-Package SoundFingerprinting\n### How it works\n[Audio Fingerprinting][emysound-how-it-works].\n\n[Video Fingerprinting][emysound-video-fingerprinting].\n\n    \n### Demo\nMy description of the algorithm alogside with the demo project can be found on [CodeProject](http://www.codeproject.com/Articles/206507/Duplicates-detector-via-audio-fingerprinting). The article is from 2011, and may be outdated.\nThe demo project is a Audio File Duplicates Detector. Its latest source code can be found [here](src/SoundFingerprinting.DuplicatesDetector). Its a WPF MVVM project that uses the algorithm to detect what files are perceptually very similar.\n\n### Contribute\nIf you want to contribute you are welcome to open issues or discuss on [issues](https://github.com/AddictedCS/soundfingerprinting/issues) page. Feel free to contact me for any remarks, ideas, bug reports etc. \n\n### License\nThe framework is provided under [MIT](https://opensource.org/licenses/MIT) license agreement.\n\n\u0026copy; Soundfingerprinting, 2010-2025, sergiu@emysound.com\n\n\n[emy-nuget]: https://www.nuget.org/packages/SoundFingerprinting.Emy\n[emysound-how-it-works]: https://emysound.com/blog/open-source/2020/06/12/how-audio-fingerprinting-works.html\n[emysound-video-fingerprinting]: https://emysound.com/blog/open-source/2021/08/01/video-fingerprinting.html\n[emysound]: https://emysound.com\n[wiki-page]: https://github.com/AddictedCS/soundfingerprinting/wiki\n[emy-wiki-page]: https://github.com/AddictedCS/soundfingerprinting/wiki/Emy-Storage\n[audio-services-wiki-page]: https://github.com/AddictedCS/soundfingerprinting/wiki/Audio-Services\n[video-fingerprinting-wiki-page]: https://github.com/AddictedCS/soundfingerprinting/wiki/Video-Fingerprints\n[seam-jump-policy-wiki-page]: https://github.com/AddictedCS/soundfingerprinting/wiki/Realtime-Seam-Jump-Policy\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faddictedcs%2Fsoundfingerprinting","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faddictedcs%2Fsoundfingerprinting","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faddictedcs%2Fsoundfingerprinting/lists"}