Skip to content

Commit

Permalink
refatory DefaultWaveformDrawing and its option.
Browse files Browse the repository at this point in the history
  • Loading branch information
MikiraSora committed Jun 24, 2023
1 parent 64717e6 commit 6629153
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 93 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
using OngekiFumenEditor.Kernel.Audio;
using OngekiFumenEditor.Base.Attributes;
using OngekiFumenEditor.Kernel.Audio;
using OngekiFumenEditor.Kernel.Graphics;
using OngekiFumenEditor.Kernel.Graphics.Drawing.DefaultDrawingImpl;
using OpenTK.Mathematics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using static OngekiFumenEditor.Kernel.Audio.ISamplePeak;

namespace OngekiFumenEditor.Modules.AudioPlayerToolViewer.Graphics.WaveformDrawing.DefaultImpls
namespace OngekiFumenEditor.Modules.AudioPlayerToolViewer.Graphics.WaveformDrawing
{
public abstract class CommonWaveformDrawingBase : CommonDrawingBase, IWaveformDrawing
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,8 @@
namespace OngekiFumenEditor.Modules.AudioPlayerToolViewer.Graphics.WaveformDrawing.DefaultImpls
{
[Export(typeof(IWaveformDrawing))]
public class DefaultWaveformDrawing : CommonWaveformDrawingBase
public partial class DefaultWaveformDrawing : CommonWaveformDrawingBase
{
private class DefaultWaveformOption : WaveformDrawingOptionBase
{
private bool onlyShowContainsObjBeat = true;
public bool OnlyShowContainsObjBeat
{
get => onlyShowContainsObjBeat;
set => Set(ref onlyShowContainsObjBeat, value);
}


private bool showContainsObjBeat = true;
public bool ShowContainsObjBeat
{
get => showContainsObjBeat;
set => Set(ref showContainsObjBeat, value);
}
}

private readonly ISimpleLineDrawing lineDrawing;
private readonly IStringDrawing stringDrawing;
private readonly SoflanList dummySoflanList;
Expand All @@ -52,7 +34,7 @@ public bool ShowContainsObjBeat
private static readonly System.Numerics.Vector4 WhiteColor = new(1, 1, 1, 1);
private static readonly System.Numerics.Vector4 IndirectorColor = new(1, 1, 0, 1);
private static readonly System.Numerics.Vector4 BeatColor = new(1, 0, 0, 1);
private static readonly System.Numerics.Vector4 ContainsObjBeatColor = new(1, 1, 0, 1);
private static readonly System.Numerics.Vector4 ObjectPlaceColor = new(1, 1, 0, 1);
private static readonly System.Numerics.Vector4 WaveformFillColor = new(100 / 255.0f, 149 / 255.0f, 237 / 255.0f, 1);

private static readonly List<(float, string)> cachedPostDrawList = new();
Expand Down Expand Up @@ -119,34 +101,6 @@ public override void Draw(IWaveformDrawingContext target, PeakPointCollection pe
var endTGrid = TGridCalculator.ConvertAudioTimeToTGrid(endTime, target.EditorViewModel);
var curTGrid = TGridCalculator.ConvertAudioTimeToTGrid(curTime, target.EditorViewModel);

cachedObjTimeMap.Clear();

void applyObjCounting(IEnumerable<ITimelineObject> timelineObjects)
{
foreach (var timeObj in timelineObjects)
{
var t = cachedObjTimeMap.TryGetValue(timeObj.TGrid, out var _t) ? _t : 0;
cachedObjTimeMap[timeObj.TGrid] = t + 1;
}
}

var fumen = editor.Fumen;
applyObjCounting(fumen.Taps.BinaryFindRange(beginTGrid, endTGrid));
applyObjCounting(fumen.Bullets.BinaryFindRange(beginTGrid, endTGrid));
applyObjCounting(fumen.Bells.BinaryFindRange(beginTGrid, endTGrid));
applyObjCounting(fumen.Beams.GetVisibleStartObjects(beginTGrid, endTGrid));
applyObjCounting(fumen.Flicks.BinaryFindRange(beginTGrid, endTGrid));
foreach (var hold in fumen.Holds.GetVisibleStartObjects(beginTGrid, endTGrid))
{
var t = cachedObjTimeMap.TryGetValue(hold.TGrid, out var _t) ? _t : 0;
cachedObjTimeMap[hold.TGrid] = t + 1;
if (hold?.HoldEnd?.TGrid is TGrid et)
{
t = cachedObjTimeMap.TryGetValue(et, out _t) ? _t : 0;
cachedObjTimeMap[et] = t + 1;
}
}

var bpmList = editor.Fumen.BpmList;
var tGridUnitLength = editor.Setting.TGridUnitLength;

Expand All @@ -158,45 +112,92 @@ void applyObjCounting(IEnumerable<ITimelineObject> timelineObjects)
var prefixOffsetX = -Math.Min(0, fromTime.TotalMilliseconds) / target.DurationMsPerPixel;
var xWidth = endX - beginX;

var beatColor = option.OnlyShowContainsObjBeat ? TransparentColor : BeatColor;
var containsObjBeatColor = option.ShowContainsObjBeat ? ContainsObjBeatColor : beatColor;

lineDrawing.Begin(target, 2);
if (option.ShowObjectPlaceLine)
{
var prevMeter = currentMeter;
var prevBpm = currentBpm;
void applyObjCounting(IEnumerable<ITimelineObject> timelineObjects)
{
foreach (var timeObj in timelineObjects)
{
var t = cachedObjTimeMap.TryGetValue(timeObj.TGrid, out var _t) ? _t : 0;
cachedObjTimeMap[timeObj.TGrid] = t + 1;
}
}

foreach ((var tGrid, var bx, var beatIdx, var meter, var bpm) in TGridCalculator.GetVisbleTimelines_DesignMode(dummySoflanList, bpmList,
editor.Fumen.MeterChanges, beginX, endX, curX, editor.Setting.BeatSplit, 1.0f, editor.Setting.TGridUnitLength))
var fumen = editor.Fumen;
applyObjCounting(fumen.Taps.BinaryFindRange(beginTGrid, endTGrid));
applyObjCounting(fumen.Bullets.BinaryFindRange(beginTGrid, endTGrid));
applyObjCounting(fumen.Bells.BinaryFindRange(beginTGrid, endTGrid));
applyObjCounting(fumen.Beams.GetVisibleStartObjects(beginTGrid, endTGrid));
applyObjCounting(fumen.Flicks.BinaryFindRange(beginTGrid, endTGrid));
foreach (var hold in fumen.Holds.GetVisibleStartObjects(beginTGrid, endTGrid))
{
var x = (float)(prefixOffsetX + aWidth * ((bx - beginX) / xWidth) - width / 2);
var t = cachedObjTimeMap.TryGetValue(hold.TGrid, out var _t) ? _t : 0;
cachedObjTimeMap[hold.TGrid] = t + 1;
if (hold?.HoldEnd?.TGrid is TGrid et)
{
t = cachedObjTimeMap.TryGetValue(et, out _t) ? _t : 0;
cachedObjTimeMap[et] = t + 1;
}
}

var beatHeightWeight = beatIdx == 0 ? 1 : 0.85f;
lineDrawing.Begin(target, 2);
{
var beatHeightWeight = 0.85f;
var topY = height / 2 * beatHeightWeight;
var buttomY = -topY;

var color = beatColor;
if (cachedObjTimeMap.ContainsKey(tGrid))
color = containsObjBeatColor;

lineDrawing.PostPoint(new(x, buttomY), TransparentColor, VertexDash.Solider);
lineDrawing.PostPoint(new(x, buttomY), color, VertexDash.Solider);
lineDrawing.PostPoint(new(x, topY), color, VertexDash.Solider);
lineDrawing.PostPoint(new(x, topY), TransparentColor, VertexDash.Solider);

var str = "";
if (prevMeter != meter)
str += $"{meter.Bunbo}/{meter.BunShi}";
if (prevBpm != bpm)
str += $" BPM:{bpm.BPM}";
if (str.Length > 0)
cachedPostDrawList.Add((x + 2, str));

prevMeter = meter;
prevBpm = bpm;
foreach (var pair in cachedObjTimeMap)
{
var tGrid = pair.Key;
var bx = TGridCalculator.ConvertTGridToY_DesignMode(tGrid, dummySoflanList, bpmList, 1, editor.Setting.TGridUnitLength);
var x = (float)(prefixOffsetX + aWidth * ((bx - beginX) / xWidth) - width / 2);

lineDrawing.PostPoint(new(x, buttomY), TransparentColor, VertexDash.Solider);
lineDrawing.PostPoint(new(x, buttomY), ObjectPlaceColor, VertexDash.Solider);
lineDrawing.PostPoint(new(x, topY), ObjectPlaceColor, VertexDash.Solider);
lineDrawing.PostPoint(new(x, topY), TransparentColor, VertexDash.Solider);
}
}
lineDrawing.End();
}

if (option.ShowTimingLine)
{
lineDrawing.Begin(target, 2);
{
var prevMeter = currentMeter;
var prevBpm = currentBpm;

foreach ((var tGrid, var bx, var beatIdx, var meter, var bpm) in TGridCalculator.GetVisbleTimelines_DesignMode(dummySoflanList, bpmList,
editor.Fumen.MeterChanges, beginX, endX, curX, editor.Setting.BeatSplit, 1.0f, editor.Setting.TGridUnitLength))
{
var x = (float)(prefixOffsetX + aWidth * ((bx - beginX) / xWidth) - width / 2);

var beatHeightWeight = beatIdx == 0 ? 1 : 0.85f;
var topY = height / 2 * beatHeightWeight;
var buttomY = -topY;

var beatColor = cachedObjTimeMap.ContainsKey(tGrid) ? TransparentColor : BeatColor;

lineDrawing.PostPoint(new(x, buttomY), TransparentColor, VertexDash.Solider);
lineDrawing.PostPoint(new(x, buttomY), beatColor, VertexDash.Solider);
lineDrawing.PostPoint(new(x, topY), beatColor, VertexDash.Solider);
lineDrawing.PostPoint(new(x, topY), TransparentColor, VertexDash.Solider);

var str = "";
if (prevMeter != meter)
str += $"{meter.Bunbo}/{meter.BunShi}";
if (prevBpm != bpm)
str += $" BPM:{bpm.BPM}";
if (str.Length > 0)
cachedPostDrawList.Add((x + 2, str));

prevMeter = meter;
prevBpm = bpm;
}
}
lineDrawing.End();
}
lineDrawing.End();

//绘制提示
foreach ((var x, var str) in cachedPostDrawList)
Expand All @@ -213,6 +214,8 @@ void applyObjCounting(IEnumerable<ITimelineObject> timelineObjects)
target,
default, out _);
}

cachedObjTimeMap.Clear();
}

//绘制当前播放时间游标
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using OngekiFumenEditor.Base.Attributes;
using System.Runtime.CompilerServices;
using System.Text.Json.Serialization;

namespace OngekiFumenEditor.Modules.AudioPlayerToolViewer.Graphics.WaveformDrawing.DefaultImpls
{
public class DefaultWaveformOption : WaveformDrawingOptionBase
{
private bool showTimingLine = true;
[ObjectPropertyBrowserShow]
[JsonInclude]
public bool ShowTimingLine
{
get => showTimingLine;
set => Set(ref showTimingLine, value);
}

private bool showObjectPlaceLine = true;
[ObjectPropertyBrowserShow]
[JsonInclude]
public bool ShowObjectPlaceLine
{
get => showObjectPlaceLine;
set => Set(ref showObjectPlaceLine, value);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
using Caliburn.Micro;
using OngekiFumenEditor.Base.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace OngekiFumenEditor.Modules.AudioPlayerToolViewer.Graphics.WaveformDrawing.DefaultImpls
{
public class WaveformDrawingOptionBase : PropertyChangedBase, IWaveformDrawingOption
{

[ObjectPropertyBrowserHide]
public override bool IsNotifying
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => base.IsNotifying;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => base.IsNotifying = value;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public partial class AudioPlayerToolViewerViewModel : IWaveformDrawingContext
private int renderViewHeight;
private IPerfomenceMonitor performenceMonitor;
private ISamplePeak samplePeak;
private IWaveformDrawing waveformDrawing;
private CancellationTokenSource loadWaveformTask;
private CancellationTokenSource resampleTaskCancelTokenSource;
private TaskCompletionSource initTask = new TaskCompletionSource();
Expand All @@ -53,6 +52,16 @@ public partial class AudioPlayerToolViewerViewModel : IWaveformDrawingContext
public TimeSpan CurrentTime { get; private set; }
public TimeSpan AudioTotalDuration => AudioPlayer?.Duration ?? default;

private IWaveformDrawing waveformDrawing;
public IWaveformDrawing WaveformDrawing
{
get => waveformDrawing;
set
{
Set(ref waveformDrawing, value);
}
}

private int resampleSize = Properties.AudioPlayerToolViewerSetting.Default.ResampleSize;
public int ResampleSize
{
Expand Down Expand Up @@ -152,7 +161,7 @@ public async void PrepareRender(GLWpfControl glView)
private void InitRender()
{
samplePeak = IoC.Get<ISamplePeak>();
waveformDrawing = IoC.Get<IWaveformDrawing>();
WaveformDrawing = IoC.Get<IWaveformDrawing>();
initTask.SetResult();
}

Expand Down Expand Up @@ -217,7 +226,7 @@ public void Render(TimeSpan ts)
UpdateDrawingContext();

if (usingPeakData is not null)
waveformDrawing.Draw(this, usingPeakData);
WaveformDrawing.Draw(this, usingPeakData);

performenceMonitor.OnAfterRender();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
xmlns:local="clr-namespace:OngekiFumenEditor.Modules.FumenMetaInfoBrowser.Views"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:objectinspector="clr-namespace:OngekiFumenEditor.UI.Controls.ObjectInspector"
xmlns:vm="clr-namespace:OngekiFumenEditor.Modules.AudioPlayerToolViewer.ViewModels"
xmlns:wpf="clr-namespace:OpenTK.Wpf;assembly=GLWpfControl"
d:Background="White"
Expand All @@ -30,6 +31,8 @@
</Grid.RowDefinitions>

<StackPanel Margin="10" IsEnabled="{Binding IsAudioButtonEnabled}">
<Line Height="2" Stroke="Red">
</Line>
<wpf:GLWpfControl
x:Name="glView"
Height="150"
Expand All @@ -43,8 +46,8 @@
<StackPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="77*" />
Expand Down Expand Up @@ -73,26 +76,31 @@
Step="2.5">
</controls:RangeValue>
<controls:RangeValue
Grid.RowSpan="2"
Grid.Row="2"
Grid.ColumnSpan="2"
Margin="0,60,10,0"
Margin="0,10,10,0"
Padding="0,5,0,5"
CurrentValue="{Binding ResampleSize, Mode=TwoWay}"
DisplayName="重采样"
MaxValue="30"
MinValue="0"
Step="1" />
<controls:RangeValue
Grid.RowSpan="2"
Grid.Row="2"
Grid.Column="2"
Margin="10,60,0,0"
Margin="10,10,0,0"
Padding="0,5,0,5"
CurrentValue="{Binding WaveformVecticalScale, Mode=TwoWay}"
DisplayName="频谱垂直缩放"
MaxValue="1.5"
MinValue="0.01"
Step="0.01" />
</Grid>
<GroupBox Header="渲染特有选项">
<objectinspector:ObjectInspectorView Margin="5,10,10,5" InspectObject="{Binding WaveformDrawing.Options}">

</objectinspector:ObjectInspectorView>
</GroupBox>
</StackPanel>
</GroupBox>
</StackPanel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ private void OnObjectChanged()
{
if (x.PropertyInfo.GetCustomAttribute<ObjectPropertyBrowserHide>() is not null)
return null;
if (x.PropertyInfo.CanWrite)
return new UndoablePropertyInfoWrapper(x, referenceEditor);
else if (x.PropertyInfo.GetCustomAttribute<ObjectPropertyBrowserShow>() is not null)
Expand Down
Loading

0 comments on commit 6629153

Please sign in to comment.