148 lines
4.8 KiB
C#
148 lines
4.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using JD.Application.View.PropertyGrid;
|
|
using JD.Asset.Types.Map;
|
|
using JD.Audio.Annotations;
|
|
using JD.Audio.Sound;
|
|
using JD.Kernel.Classes;
|
|
using JD.Kernel.Structs;
|
|
using JD.LogService;
|
|
using TeaBox;
|
|
using JD.Serialization;
|
|
|
|
|
|
namespace JD.Application.Utils
|
|
{
|
|
public static class TapeExtensions
|
|
{
|
|
#region Wave
|
|
|
|
public static void SetWave(this Tape tape, Wave wave)
|
|
{
|
|
tape.Extensions.wave = wave ?? _emptyWave;
|
|
tape.RaisePropertyChanged("Wave");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Not a real TryGet, returns right Wave if found, else returns an empty Wave with test info
|
|
/// </summary>
|
|
/// <param name="tape"></param>
|
|
/// <returns></returns>
|
|
public static Wave TryGetWave(this Tape tape)
|
|
{
|
|
if (tape.Extensions.wave == null && tape.Extensions.triedToFindWave == null)
|
|
{
|
|
tape.Extensions.triedToFindWave = true;
|
|
tape.Extensions.wave = ResolveWaveFromTape(tape);
|
|
}
|
|
|
|
return tape.Extensions.wave ?? _emptyWave;
|
|
}
|
|
|
|
private static Wave ResolveWaveFromTape(Tape tape)
|
|
{
|
|
try
|
|
{
|
|
var map = Map.FromPath(tape.Id);
|
|
|
|
if (map.IsValid)
|
|
{
|
|
var musicTrackTpl = map.MusicTrack;
|
|
|
|
if (!string.IsNullOrEmpty(musicTrackTpl) && !File.Exists(musicTrackTpl))
|
|
{
|
|
throw new IOException($"Could not find the MusicTrackTpl file for map {map.Name} at location {musicTrackTpl}");
|
|
}
|
|
|
|
return Wave.LoadFromMusicTrackTpl(musicTrackTpl);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageService.MessageService.ShowBalloon(TimeSpan.FromSeconds(15), "No wave available", "Could not resolve the wave associated with tape " + tape.Id + ". Details : " + ex.Message, ToolTipIcon.Warning);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static object GridWave(this Tape tape)
|
|
{
|
|
return tape.TryGetWave() != null ? new WaveGridView(tape.TryGetWave()) : null;
|
|
}
|
|
|
|
private static readonly Wave _emptyWave = CreateEmptyWave();
|
|
|
|
private static Wave CreateEmptyWave()
|
|
{
|
|
const int sampleCount = 10000;
|
|
const int emptyWaveLengthInMinutes = 3;
|
|
|
|
var channel = new Channel(sampleCount);
|
|
for (int i = 0; i < sampleCount; i++)
|
|
{
|
|
channel.Add(0);
|
|
}
|
|
|
|
var wave = new Wave(new[] { channel }, TimeSpan.FromMinutes(emptyWaveLengthInMinutes));
|
|
using (wave.Annotations.BeginUpdate())
|
|
{
|
|
const int bpm = 120;
|
|
double markerCount = wave.Duration.TotalMinutes * bpm;
|
|
for (int i = 0; i < markerCount; i++)
|
|
{
|
|
wave.Annotations.Markers.Add(new Beat(TimeSpan.FromMinutes((double)i / bpm),
|
|
(int)(((double)i / markerCount) * sampleCount), ""));
|
|
}
|
|
}
|
|
return wave;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Replication
|
|
|
|
public static Scope ReplicationOperation(this Tape tape)
|
|
{
|
|
return tape.Extensions.IsReplicating ?? (tape.Extensions.IsReplicating = new Scope());
|
|
}
|
|
|
|
/// <summary>
|
|
/// The update operation is useful when the tape will be modified a lot.
|
|
/// </summary>
|
|
public static Scope UpdateOperation(this Tape tape)
|
|
{
|
|
return tape.Extensions.UpdateOperation ?? (tape.Extensions.UpdateOperation = new Scope());
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Validation
|
|
|
|
/// <summary>
|
|
/// Makes sure two clips are not wearing the same id.
|
|
/// </summary>
|
|
public static void SanitizeClipIds(this Tape tape, ILogger log)
|
|
{
|
|
var clipById = new Dictionary<uint, Clip>();
|
|
foreach (var clip in tape.Clips.ToArray())
|
|
{
|
|
Clip existingClip;
|
|
if (clipById.TryGetValue(clip.Id, out existingClip))
|
|
{
|
|
clip.Id = IdGenerator.Instance.Generate();
|
|
|
|
var location = new FileLocation(tape.Id, new List<uint> { existingClip.Id, clip.Id });
|
|
log.LogWarning(location, "Two clips are sharing the same id {0}. Second one was reassigned to a new one.", clip.Id);
|
|
}
|
|
else
|
|
{
|
|
clipById.Add(clip.Id, clip);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|