Skip to content

Commit

Permalink
Merge pull request #40 from pavel-zhur/feature/key-detection-12
Browse files Browse the repository at this point in the history
Feature/key detection 12
  • Loading branch information
pavel-zhur authored Jul 16, 2024
2 parents 418e0b2 + 2e8a39e commit 62b6538
Show file tree
Hide file tree
Showing 220 changed files with 8,818 additions and 1,400 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -370,3 +370,4 @@ FodyWeavers.xsd
/OneShelf.Frontend/OneShelf.Frontend.Web/wwwroot/appsettings.Development-mobile-remote.json
/OneShelf.Frontend/OneShelf.Frontend.Web/wwwroot/appsettings.Development-mobile.json
/OneShelf.Frontend/OneShelf.Frontend.Web/wwwroot/appsettings.Development-remote.json
/HarmonyDB.Playground/HarmonyDB.Playground.Web/appsettings.Development-remote.json
21 changes: 21 additions & 0 deletions HarmonyDB and OneShelf.sln
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarmonyDB.Playground.Web",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarmonyDB.Common.FullTextSearch", "HarmonyDB.Common\HarmonyDB.Common.FullTextSearch\HarmonyDB.Common.FullTextSearch.csproj", "{21D494EB-BDD0-49B0-A79D-57AE6A529F4D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarmonyDB.Index.LongBalancer", "HarmonyDB.Index\HarmonyDB.Index.LongBalancer\HarmonyDB.Index.LongBalancer.csproj", "{59DD2309-74F4-4DBC-B98C-BB4E93AB08C2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarmonyDB.Index.Analysis.Em", "HarmonyDB.Index\HarmonyDB.Index.Analysis.Em\HarmonyDB.Index.Analysis.Em.csproj", "{33A0E860-62DF-41C6-8E25-442FA2BC625F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneShelf.Common.Api.Common", "OneShelf.Common\OneShelf.Common.Api.Common\OneShelf.Common.Api.Common.csproj", "{C918C6DF-8C9B-4EB9-B509-58E0CC774771}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -427,6 +433,18 @@ Global
{21D494EB-BDD0-49B0-A79D-57AE6A529F4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21D494EB-BDD0-49B0-A79D-57AE6A529F4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{21D494EB-BDD0-49B0-A79D-57AE6A529F4D}.Release|Any CPU.Build.0 = Release|Any CPU
{59DD2309-74F4-4DBC-B98C-BB4E93AB08C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{59DD2309-74F4-4DBC-B98C-BB4E93AB08C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59DD2309-74F4-4DBC-B98C-BB4E93AB08C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59DD2309-74F4-4DBC-B98C-BB4E93AB08C2}.Release|Any CPU.Build.0 = Release|Any CPU
{33A0E860-62DF-41C6-8E25-442FA2BC625F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33A0E860-62DF-41C6-8E25-442FA2BC625F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33A0E860-62DF-41C6-8E25-442FA2BC625F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33A0E860-62DF-41C6-8E25-442FA2BC625F}.Release|Any CPU.Build.0 = Release|Any CPU
{C918C6DF-8C9B-4EB9-B509-58E0CC774771}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C918C6DF-8C9B-4EB9-B509-58E0CC774771}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C918C6DF-8C9B-4EB9-B509-58E0CC774771}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C918C6DF-8C9B-4EB9-B509-58E0CC774771}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -495,6 +513,9 @@ Global
{F2CFF546-5D77-4E7D-BE8B-611022AD6ECA} = {7548FF8E-E1B9-4939-96E9-03DBD5236709}
{C63D176C-03AB-4403-BE88-E8FE4EFE736D} = {47FED0C3-B336-4FC6-86FE-51A78872C2DE}
{21D494EB-BDD0-49B0-A79D-57AE6A529F4D} = {2950865E-9D1A-406E-B0C6-4C249E2E4D61}
{59DD2309-74F4-4DBC-B98C-BB4E93AB08C2} = {7548FF8E-E1B9-4939-96E9-03DBD5236709}
{33A0E860-62DF-41C6-8E25-442FA2BC625F} = {7548FF8E-E1B9-4939-96E9-03DBD5236709}
{C918C6DF-8C9B-4EB9-B509-58E0CC774771} = {2AD8DB5A-A1C3-4116-B8C5-D8DA505B1CC5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {59093261-FDDA-411A-852D-EA21AEF83E07}
Expand Down
10 changes: 10 additions & 0 deletions HarmonyDB and OneShelf.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeObjectCreationWhenTypeEvident/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeObjectCreationWhenTypeNotEvident/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeThisQualifier/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CssNotResolved/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=FieldCanBeMadeReadOnly_002ELocal/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InconsistentNaming/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InvalidXmlDocComment/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InvokeAsExtensionMethod/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MergeConditionalExpression/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MergeIntoPattern/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MethodHasAsyncOverload/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=Mvc_002EActionNotResolved/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=Mvc_002EViewNotResolved/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantEmptyObjectCreationArgumentList/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantStringInterpolation/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StructuredMessageTemplateProblem/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FBuiltInTypes/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FElsewhere/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SwitchExpressionHandlesSomeKnownEnumValuesWithExceptionInDefault/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SwitchStatementHandlesSomeKnownEnumValuesWithDefault/@EntryIndexedValue">ERROR</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/OBJECT_CREATION_WHEN_TYPE_NOT_EVIDENT/@EntryValue">TargetTyped</s:String>
Expand All @@ -20,11 +27,14 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Folclore/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Interims/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Localizer/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=loopify/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Overscroll/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=participations/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Pdfs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Poller/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Redownload/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=subloop/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Subloops/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Unsynced/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Upsert/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Wantlist/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
42 changes: 21 additions & 21 deletions HarmonyDB.Common/HarmonyDB.Common.Representations.OneShelf/Note.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ public record Note
{
public const int Modulus = 12;

public int Value { get; init; }
public byte Value { get; init; }
public NoteAlteration? Alteration { get; init; }

public Note()
{
}

public Note(int value, NoteAlteration? alteration = null)
public Note(byte value, NoteAlteration? alteration = null)
{
Value = value;
Alteration = alteration;
Expand All @@ -25,18 +25,18 @@ public Note(int value, NoteAlteration? alteration = null)
public static Note F { get; } = new(8);
public static Note G { get; } = new(10);

public static readonly IReadOnlyList<int> Major = new List<int>
public static readonly IReadOnlyList<byte> Major = new List<byte>
{
A.Value,
B.Value,
C.Value + 1,
(byte)(C.Value + 1),
D.Value,
E.Value,
F.Value + 1,
G.Value + 1,
(byte)(F.Value + 1),
(byte)(G.Value + 1),
};

public static readonly IReadOnlyList<int> Minor = new List<int>
public static readonly IReadOnlyList<byte> Minor = new List<byte>
{
A.Value,
B.Value,
Expand All @@ -52,15 +52,16 @@ public Note(int value, NoteAlteration? alteration = null)
{ 'A', A },
{ 'B', B },
{ 'C', C },
{ 'С', C }, // russian
{ 'D', D },
{ 'E', E },
{ 'F', F },
{ 'G', G },
{ 'H', B },
};

private static IReadOnlyDictionary<int, char> NotesToCharacters { get; } = CharactersToNotes
.Where(x => x.Key != 'H')
private static IReadOnlyDictionary<byte, char> NotesToCharacters { get; } = CharactersToNotes
.Where(x => x.Key is not ('H' or 'С')) // russian 'С'
.ToDictionary(x => x.Value.Value, x => x.Key);

public static Note Max { get; } = new(11);
Expand All @@ -73,7 +74,7 @@ static Note()
var circleOfFifths = new List<(Note, Note, bool isSharps)>();

var current = new Note(3).Add(-7);
for (var i = 0; i < 12; i++)
for (var i = 0; i < Modulus; i++)
{
var isSharps = i <= 6;

Expand All @@ -95,23 +96,23 @@ x with
}

public Note Sharp() => new(
Value == Max.Value ? Min.Value : Value + 1,
Value == Max.Value ? Min.Value : (byte)(Value + 1),
NoteAlteration.Sharp);

public Note Flat() => new(
Value == Min.Value ? Max.Value : Value - 1,
Value == Min.Value ? Max.Value : (byte)((Value + Modulus - 1) % Modulus),
NoteAlteration.Flat);

public Note Add(int delta)
{
var newValue = Value + delta;
newValue %= 12;
newValue %= Modulus;
if (newValue < Min.Value)
{
newValue += 12;
newValue += Modulus;
}

return new(newValue);
return new((byte)newValue);
}

public string Representation(RepresentationSettings representationSettings)
Expand All @@ -122,7 +123,6 @@ public string Representation(RepresentationSettings representationSettings)
{
var (note, major) = representationSettings.RelativeTo.Value;
var scale = major ? Major : Minor;
var isSharps = CircleOfFifths.Single(x => (major ? x.major : x.minor).Value == note).isSharps;
scale = scale.Select(n => new Note(n).Add(note).Add(-representationSettings.Transpose).Value).ToList();
var found = scale.Select((x, i) => (x, i: i + 1)).SingleOrDefault(x => x.x == Value).i;
if (found > 0) return found.ToString();
Expand All @@ -132,7 +132,7 @@ public string Representation(RepresentationSettings representationSettings)
var preferredAlteration = Alteration;
if (representationSettings.Transpose != 0)
{
value = (value + Modulus + representationSettings.Transpose) % Modulus;
value = (byte)((value + Modulus + representationSettings.Transpose) % Modulus);
preferredAlteration = null;
}

Expand All @@ -145,22 +145,22 @@ public string Representation(RepresentationSettings representationSettings)
switch (preferredAlteration)
{
case NoteAlteration.Flat:
return $"{NotesToCharacters[value == Max.Value ? Min.Value : value + 1]}{SignsConstants.SignFlat}";
return $"{NotesToCharacters[(byte)(value == Max.Value ? Min.Value : value + 1)]}{SignsConstants.SignFlat}";

case NoteAlteration.Sharp:
return $"{NotesToCharacters[value == Min.Value ? Max.Value : value - 1]}{SignsConstants.SignSharp}";
return $"{NotesToCharacters[(byte)(value == Min.Value ? Max.Value : value - 1)]}{SignsConstants.SignSharp}";

default:
throw new ArgumentOutOfRangeException();
}
}

public int Tone(RepresentationSettings representationSettings)
public byte Tone(RepresentationSettings representationSettings)
{
var value = Value;
if (representationSettings.Transpose != 0)
{
value = (value + Modulus + representationSettings.Transpose) % Modulus;
value = (byte)((value + Modulus + representationSettings.Transpose) % Modulus);
}

return value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

public static class TranspositionExtensions
{
public static string Transposition(this byte transposition)
=> ((int)transposition).Transposition();

public static string Transposition(this int transposition)
=> transposition switch
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageReadmeFile>readme.md</PackageReadmeFile>
</PropertyGroup>

<ItemGroup>
<None Include="..\..\nuget readme.md" Pack="true" Link="nuget readme.md" PackagePath="\readme.md" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
</ItemGroup>

</Project>
28 changes: 28 additions & 0 deletions HarmonyDB.Index/HarmonyDB.Index.Analysis.Em/Models/Constants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace HarmonyDB.Index.Analysis.Em.Models;

public static class Constants
{
public const int TonicCount = 12; // Number of different tonics
public const int ScaleCount = 2; // Major and Minor

public static IReadOnlyList<(byte tonic, byte scale)> Indices { get; }
= Enumerable
.Range(0, TonicCount)
.SelectMany(i => Enumerable.Range(0, ScaleCount).Select(j => ((byte)i, (byte)j)))
.ToList();

public static IReadOnlyList<(byte tonic, Scale scale)> Pairs { get; }
= Indices.Select(x => (x.tonic, (Scale)x.scale)).ToList();

public static int GetMajorTonic((byte tonic, Scale scale) scale, bool isSong)
{
return scale.scale == Scale.Major ? scale.tonic : GetRelativeScale(scale, isSong).tonic;
}

public static (byte tonic, Scale scale) GetRelativeScale((byte tonic, Scale scale) scale, bool isSong)
{
return scale.scale == Scale.Major
? ((byte)((scale.tonic + (isSong ? -3 : 3) + TonicCount) % TonicCount), Scale.Minor)
: ((byte)((scale.tonic + (isSong ? 3 : -3) + TonicCount) % TonicCount), Scale.Major);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace HarmonyDB.Index.Analysis.Em.Models;

public sealed class EmContext
{
public required ILookup<string, LoopLink> LoopLinksBySongId { get; init; }
public required ILookup<string, LoopLink> LoopLinksByLoopId { get; init; }
public required IReadOnlyDictionary<string, int> SongCounts { get; init; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace HarmonyDB.Index.Analysis.Em.Models;

public interface IEmModel
{
IReadOnlyCollection<Song> Songs { get; }
IReadOnlyCollection<Loop> Loops { get; }
}
8 changes: 8 additions & 0 deletions HarmonyDB.Index/HarmonyDB.Index.Analysis.Em/Models/ISource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace HarmonyDB.Index.Analysis.Em.Models;

public interface ISource
{
string Id { get; }
float[,] TonalityProbabilities { get; set; } // [TonicCount, ScaleCount]
(float TonicScore, float ScaleScore) Score { get; set; }
}
8 changes: 8 additions & 0 deletions HarmonyDB.Index/HarmonyDB.Index.Analysis.Em/Models/Loop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace HarmonyDB.Index.Analysis.Em.Models;

public class Loop : ISource
{
public required string Id { get; init; }
public float[,] TonalityProbabilities { get; set; } = new float[Constants.TonicCount, Constants.ScaleCount];
public (float TonicScore, float ScaleScore) Score { get; set; }
}
11 changes: 11 additions & 0 deletions HarmonyDB.Index/HarmonyDB.Index.Analysis.Em/Models/LoopLink.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace HarmonyDB.Index.Analysis.Em.Models;

public record LoopLink
{
public required Loop Loop { get; init; }
public required Song Song { get; init; }
public string SongId => Song.Id;
public string LoopId => Loop.Id;
public required byte Shift { get; init; }
public required float Weight { get; init; }
}
7 changes: 7 additions & 0 deletions HarmonyDB.Index/HarmonyDB.Index.Analysis.Em/Models/Scale.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace HarmonyDB.Index.Analysis.Em.Models;

public enum Scale : byte
{
Major,
Minor
}
9 changes: 9 additions & 0 deletions HarmonyDB.Index/HarmonyDB.Index.Analysis.Em/Models/Song.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace HarmonyDB.Index.Analysis.Em.Models;

public class Song : ISource
{
public required string Id { get; init; }
public float[,] TonalityProbabilities { get; set; } = new float[Constants.TonicCount, Constants.ScaleCount];
public (float TonicScore, float ScaleScore) Score { get; set; }
public required (byte Tonic, Scale Scale)? KnownTonality { get; init; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using HarmonyDB.Index.Analysis.Em.Services;
using Microsoft.Extensions.DependencyInjection;

namespace HarmonyDB.Index.Analysis.Em;

public static class ServiceCollectionExtensions
{
public static IServiceCollection AddIndexAnalysisEm(this IServiceCollection services) => services
.AddSingleton<MusicAnalyzer>();
}
Loading

0 comments on commit 62b6538

Please sign in to comment.