1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 20:47:28 +08:00

Back to using SampleInfo + fix taiko beatmap conversion.

This commit is contained in:
smoogipooo 2017-04-06 11:41:16 +09:00
parent e903241c7b
commit eb82a4c090
19 changed files with 178 additions and 164 deletions

View File

@ -43,7 +43,7 @@ namespace osu.Game.Modes.Osu.Beatmaps
return new Slider
{
StartTime = original.StartTime,
SampleBanks = original.SampleBanks,
Samples = original.Samples,
CurveObject = curveData,
Position = positionData?.Position ?? Vector2.Zero,
NewCombo = comboData?.NewCombo ?? false
@ -55,7 +55,7 @@ namespace osu.Game.Modes.Osu.Beatmaps
return new Spinner
{
StartTime = original.StartTime,
SampleBanks = original.SampleBanks,
Samples = original.Samples,
Position = new Vector2(512, 384) / 2,
EndTime = endTimeData.EndTime
};
@ -64,7 +64,7 @@ namespace osu.Game.Modes.Osu.Beatmaps
return new HitCircle
{
StartTime = original.StartTime,
SampleBanks = original.SampleBanks,
Samples = original.Samples,
Position = positionData?.Position ?? Vector2.Zero,
NewCombo = comboData?.NewCombo ?? false
};

View File

@ -67,7 +67,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
ComboIndex = s.ComboIndex,
Scale = s.Scale,
ComboColour = s.ComboColour,
SampleBanks = s.SampleBanks,
Samples = s.Samples,
}),
};

View File

@ -2,17 +2,12 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps.Samples;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Osu.Judgements;
using OpenTK;
using OpenTK.Graphics;
using System.Collections.Generic;
namespace osu.Game.Modes.Osu.Objects.Drawables
{
@ -29,8 +24,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
protected override OsuJudgement CreateJudgement() => new OsuJudgement { MaxScore = OsuScoreResult.SliderTick };
private List<SampleChannel> samples = new List<SampleChannel>();
public DrawableSliderTick(SliderTick sliderTick) : base(sliderTick)
{
this.sliderTick = sliderTick;
@ -56,18 +49,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
};
}
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
foreach (var bank in HitObject.SampleBanks)
samples.Add(audio.Sample.Get($@"Gameplay/{bank.Name}-slidertick"));
}
protected override void PlaySamples()
{
samples.ForEach(s => s?.Play());
}
protected override void CheckJudgement(bool userTriggered)
{
if (Judgement.TimeOffset >= 0)

View File

@ -2,13 +2,14 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Game.Beatmaps.Samples;
using osu.Game.Beatmaps.Timing;
using osu.Game.Modes.Objects.Types;
using System;
using System.Collections.Generic;
using osu.Game.Modes.Objects;
using osu.Game.Database;
using System.Linq;
using osu.Game.Audio;
namespace osu.Game.Modes.Osu.Objects
{
@ -95,7 +96,12 @@ namespace osu.Game.Modes.Osu.Objects
StackHeight = StackHeight,
Scale = Scale,
ComboColour = ComboColour,
SampleBanks = SampleBanks
Samples = Samples.Select(s => new SampleInfo
{
Bank = s.Bank,
Name = @"slidertick",
Volume = s.Volume
}).ToList()
};
}
}

View File

@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Samples;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Types;
using osu.Game.Modes.Taiko.Objects;
@ -10,6 +9,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Database;
using osu.Game.Audio;
namespace osu.Game.Modes.Taiko.Beatmaps
{
@ -57,9 +57,9 @@ namespace osu.Game.Modes.Taiko.Beatmaps
var endTimeData = obj as IHasEndTime;
// Old osu! used hit sounding to determine various hit type information
List<SampleBank> sampleBanks = obj.SampleBanks;
List<SampleInfo> samples = obj.Samples;
bool strong = sampleBanks.Any(b => b.Samples.Any(s => s.Type == SampleType.Finish));
bool strong = samples.Any(s => s.Name == @"hitfinish");
if (distanceData != null)
{
@ -98,7 +98,7 @@ namespace osu.Game.Modes.Taiko.Beatmaps
yield return new CentreHit
{
StartTime = j,
SampleBanks = obj.SampleBanks,
Samples = obj.Samples,
IsStrong = strong,
VelocityMultiplier = legacy_velocity_multiplier
};
@ -109,7 +109,7 @@ namespace osu.Game.Modes.Taiko.Beatmaps
yield return new DrumRoll
{
StartTime = obj.StartTime,
SampleBanks = obj.SampleBanks,
Samples = obj.Samples,
IsStrong = strong,
Distance = distance,
TickRate = beatmap.BeatmapInfo.Difficulty.SliderTickRate == 3 ? 3 : 4,
@ -124,7 +124,7 @@ namespace osu.Game.Modes.Taiko.Beatmaps
yield return new Swell
{
StartTime = obj.StartTime,
SampleBanks = obj.SampleBanks,
Samples = obj.Samples,
IsStrong = strong,
EndTime = endTimeData.EndTime,
RequiredHits = (int)Math.Max(1, endTimeData.Duration / 1000 * hitMultiplier),
@ -133,24 +133,24 @@ namespace osu.Game.Modes.Taiko.Beatmaps
}
else
{
bool isCentre = sampleBanks.Any(b => b.Samples.Any(s => s.Type == SampleType.Normal));
bool isRim = samples.Any(s => s.Name == @"hitclap" || s.Name == @"hitwhistle");
if (isCentre)
if (isRim)
{
yield return new CentreHit
yield return new RimHit
{
StartTime = obj.StartTime,
SampleBanks = obj.SampleBanks,
Samples = obj.Samples,
IsStrong = strong,
VelocityMultiplier = legacy_velocity_multiplier
};
}
else
{
yield return new RimHit
yield return new CentreHit
{
StartTime = obj.StartTime,
SampleBanks = obj.SampleBanks,
Samples = obj.Samples,
IsStrong = strong,
VelocityMultiplier = legacy_velocity_multiplier
};

View File

@ -1,13 +1,13 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps.Samples;
using osu.Game.Modes.Objects.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps.Timing;
using osu.Game.Database;
using osu.Game.Audio;
namespace osu.Game.Modes.Taiko.Objects
{
@ -95,7 +95,12 @@ namespace osu.Game.Modes.Taiko.Objects
TickSpacing = tickSpacing,
StartTime = t,
IsStrong = IsStrong,
SampleBanks = SampleBanks
Samples = Samples.Select(s => new SampleInfo
{
Bank = s.Bank,
Name = @"slidertick",
Volume = s.Volume
}).ToList()
});
first = false;

View File

@ -6,7 +6,6 @@ using NUnit.Framework;
using OpenTK;
using OpenTK.Graphics;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.Samples;
using osu.Game.Modes;
using osu.Game.Tests.Resources;
using osu.Game.Modes.Osu;
@ -137,12 +136,12 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.IsNotNull(slider);
Assert.AreEqual(new Vector2(192, 168), slider.Position);
Assert.AreEqual(956, slider.StartTime);
Assert.IsTrue(slider.SampleBanks.Any(b => b.Name == "none"));
Assert.IsTrue(slider.Samples.Any(s => s.Name == @"normal"));
var hit = beatmap.HitObjects[1] as LegacyHit;
Assert.IsNotNull(hit);
Assert.AreEqual(new Vector2(304, 56), hit.Position);
Assert.AreEqual(1285, hit.StartTime);
Assert.IsTrue(hit.SampleBanks.Any(b => b.Name == "clap"));
Assert.IsTrue(hit.Samples.Any(s => s.Name == @"clap"));
}
}
}

View File

@ -0,0 +1,21 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Audio.Sample;
using osu.Framework.IO.Stores;
namespace osu.Game.Audio
{
public class BeatmapSampleStore : NamespacedResourceStore<SampleChannel>
{
public BeatmapSampleStore(IResourceStore<SampleChannel> store, string ns)
: base(store, ns)
{
}
public SampleChannel Get(SampleInfo sampleInfo)
{
return Get($@"{sampleInfo.Bank}-{sampleInfo.Name}");
}
}
}

View File

@ -0,0 +1,23 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Audio
{
public class SampleInfo
{
/// <summary>
/// The bank to load the sample from.
/// </summary>
public string Bank;
/// <summary>
/// The name of the sample to load.
/// </summary>
public string Name;
/// <summary>
/// The sample volume.
/// </summary>
public int Volume;
}
}

View File

@ -6,7 +6,6 @@ using System.Globalization;
using System.IO;
using OpenTK.Graphics;
using osu.Game.Beatmaps.Events;
using osu.Game.Beatmaps.Samples;
using osu.Game.Beatmaps.Timing;
using osu.Game.Modes;
using osu.Game.Modes.Objects;
@ -247,6 +246,10 @@ namespace osu.Game.Beatmaps.Formats
omitFirstBarSignature = (effectFlags & 8) > 0;
}
string stringSampleSet = sampleSet.ToString().ToLower();
if (stringSampleSet == "none")
stringSampleSet = "normal";
beatmap.TimingInfo.ControlPoints.Add(new ControlPoint
{
Time = time,
@ -254,11 +257,8 @@ namespace osu.Game.Beatmaps.Formats
VelocityAdjustment = beatLength < 0 ? -beatLength / 100.0 : 1,
TimingChange = timingChange,
TimeSignature = timeSignature,
SampleBank = new SampleBank
{
Name = sampleSet.ToString().ToLower(),
Volume = sampleVolume
},
SampleBank = stringSampleSet,
SampleVolume = sampleVolume,
KiaiMode = kiaiMode,
OmitFirstBarLine = omitFirstBarSignature
});

View File

@ -1,21 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Beatmaps.Samples
{
/// <summary>
/// A <see cref="Sample"/> defines a type of sound that is to be played.
/// </summary>
public class Sample
{
/// <summary>
/// The type of sound to be played.
/// </summary>
public SampleType Type;
/// <summary>
/// The volume to be played at.
/// </summary>
public int? Volume;
}
}

View File

@ -1,29 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
namespace osu.Game.Beatmaps.Samples
{
/// <summary>
/// Wraps a list of <see cref="Sample"/> to change which bank of files are used for each <see cref="Sample"/>.
/// </summary>
public class SampleBank
{
/// <summary>
/// The list of samples that are to be played to be played from this bank.
/// </summary>
public List<Sample> Samples = new List<Sample>();
/// <summary>
/// In conversion from osu-stable, this is equivalent to SampleSet (_not_ CustomSampleSet).
/// i.e. None/Normal/Soft/Drum
/// </summary>
public string Name;
/// <summary>
/// Default sample volume.
/// </summary>
public int Volume;
}
}

View File

@ -1,13 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Beatmaps.Samples
{
public enum SampleType
{
Normal,
Whistle,
Finish,
Clap
}
}

View File

@ -1,8 +1,6 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps.Samples;
namespace osu.Game.Beatmaps.Timing
{
public class ControlPoint
@ -13,7 +11,9 @@ namespace osu.Game.Beatmaps.Timing
TimingChange = true,
};
public SampleBank SampleBank;
public string SampleBank;
public int SampleVolume;
public TimeSignatures TimeSignature;
public double Time;
public double BeatLength;

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps.Samples;
using osu.Game.Modes;
using SQLite.Net.Attributes;
using SQLiteNetExtensions.Attributes;

View File

@ -7,11 +7,11 @@ using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Game.Beatmaps.Samples;
using osu.Game.Modes.Judgements;
using Container = osu.Framework.Graphics.Containers.Container;
using osu.Game.Modes.Objects.Types;
using OpenTK.Graphics;
using osu.Game.Audio;
namespace osu.Game.Modes.Objects.Drawables
{
@ -50,6 +50,7 @@ namespace osu.Game.Modes.Objects.Drawables
public TObject HitObject;
private readonly List<SampleChannel> samples = new List<SampleChannel>();
private AudioManager audio;
protected DrawableHitObject(TObject hitObject)
{
@ -59,9 +60,10 @@ namespace osu.Game.Modes.Objects.Drawables
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
foreach (var bank in HitObject.SampleBanks)
foreach (var sample in bank.Samples)
samples.Add(audio.Sample.Get($@"Gameplay/{bank.Name}-hit{sample.Type.ToString().ToLower()}"));
this.audio = audio;
foreach (var sample in HitObject.Samples)
samples.Add(GetSample(sample));
}
private ArmedState state;
@ -155,9 +157,21 @@ namespace osu.Game.Modes.Objects.Drawables
UpdateJudgement(false);
}
protected SampleChannel GetSample(SampleInfo sampleInfo)
{
SampleChannel ret = audio.Sample.Get($@"Gameplay/{sampleInfo.Bank}-{sampleInfo.Name}");
ret.Volume.Value = sampleInfo.Volume;
return ret;
}
protected virtual void PlaySamples()
{
samples.ForEach(s => s?.Play());
samples.ForEach(s =>
{
s?.Play();
});
}
private List<DrawableHitObject<TObject, TJudgement>> nestedHitObjects;

View File

@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps.Samples;
using osu.Game.Audio;
using osu.Game.Beatmaps.Timing;
using osu.Game.Database;
using System.Collections.Generic;
@ -22,9 +22,9 @@ namespace osu.Game.Modes.Objects
public double StartTime { get; set; }
/// <summary>
/// The sample banks to be played when this hit object is hit.
/// The samples to be played when this hit object is hit.
/// </summary>
public List<SampleBank> SampleBanks = new List<SampleBank>();
public List<SampleInfo> Samples = new List<SampleInfo>();
/// <summary>
/// Applies default values to this HitObject.
@ -33,17 +33,19 @@ namespace osu.Game.Modes.Objects
/// <param name="timing">The timing settings to use.</param>
public virtual void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty)
{
foreach (var bank in SampleBanks)
ControlPoint overridePoint;
ControlPoint timingPoint = timing.TimingPointAt(StartTime, out overridePoint);
foreach (var sample in Samples)
{
if (!string.IsNullOrEmpty(bank.Name) && bank.Name != @"none")
if (sample.Volume == 0)
sample.Volume = (overridePoint ?? timingPoint)?.SampleVolume ?? 0;
// If the bank is not assigned a name, assign it from the control point
if (!string.IsNullOrEmpty(sample.Bank))
continue;
// If the bank is not assigned a name, assign it from the relevant timing point
ControlPoint overridePoint;
ControlPoint timingPoint = timing.TimingPointAt(StartTime, out overridePoint);
bank.Name = (overridePoint ?? timingPoint)?.SampleBank.Name ?? string.Empty;
bank.Volume = (overridePoint ?? timingPoint)?.SampleBank.Volume ?? 0;
sample.Bank = (overridePoint ?? timingPoint)?.SampleBank ?? string.Empty;
}
}
}

View File

@ -7,8 +7,8 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using osu.Game.Modes.Objects.Legacy;
using osu.Game.Beatmaps.Samples;
using osu.Game.Beatmaps.Formats;
using osu.Game.Audio;
namespace osu.Game.Modes.Objects
{
@ -21,8 +21,9 @@ namespace osu.Game.Modes.Objects
bool combo = type.HasFlag(LegacyHitObjectType.NewCombo);
type &= ~LegacyHitObjectType.NewCombo;
var normalSampleBank = new SampleBank();
var addSampleBank = new SampleBank();
int sampleVolume = 0;
string normalSampleBank = string.Empty;
string addSampleBank = string.Empty;
HitObject result;
@ -35,7 +36,7 @@ namespace osu.Game.Modes.Objects
};
if (split.Length > 5)
readCustomSampleBanks(split[5], ref normalSampleBank, ref addSampleBank);
readCustomSampleBanks(split[5], ref normalSampleBank, ref addSampleBank, ref sampleVolume);
}
else if ((type & LegacyHitObjectType.Slider) > 0)
{
@ -93,7 +94,7 @@ namespace osu.Game.Modes.Objects
};
if (split.Length > 10)
readCustomSampleBanks(split[10], ref normalSampleBank, ref addSampleBank);
readCustomSampleBanks(split[10], ref normalSampleBank, ref addSampleBank, ref sampleVolume);
}
else if ((type & LegacyHitObjectType.Spinner) > 0)
{
@ -103,11 +104,15 @@ namespace osu.Game.Modes.Objects
};
if (split.Length > 6)
readCustomSampleBanks(split[6], ref normalSampleBank, ref addSampleBank);
readCustomSampleBanks(split[6], ref normalSampleBank, ref addSampleBank, ref sampleVolume);
}
else if ((type & LegacyHitObjectType.Hold) > 0)
{
// Note: Hold is generated by BMS converts
// Todo: Apparently end time is determined by samples??
// Shouldn't be needed until mania
result = new LegacyHold
{
Position = new Vector2(int.Parse(split[0]), int.Parse(split[1])),
@ -121,45 +126,68 @@ namespace osu.Game.Modes.Objects
var soundType = (LegacySoundType)int.Parse(split[4]);
normalSampleBank.Samples.Add(new Sample { Type = SampleType.Normal });
if ((soundType & LegacySoundType.Finish) > 0)
addSampleBank.Samples.Add(new Sample { Type = SampleType.Finish });
if ((soundType & LegacySoundType.Whistle) > 0)
addSampleBank.Samples.Add(new Sample { Type = SampleType.Whistle });
if ((soundType & LegacySoundType.Clap) > 0)
addSampleBank.Samples.Add(new Sample { Type = SampleType.Clap });
result.Samples.Add(new SampleInfo
{
Bank = normalSampleBank,
Name = "hitnormal",
Volume = sampleVolume
});
result.SampleBanks.Add(normalSampleBank);
result.SampleBanks.Add(addSampleBank);
if ((soundType & LegacySoundType.Finish) > 0)
{
result.Samples.Add(new SampleInfo
{
Bank = addSampleBank,
Name = "hitfinish",
Volume = sampleVolume
});
}
if ((soundType & LegacySoundType.Whistle) > 0)
{
result.Samples.Add(new SampleInfo
{
Bank = addSampleBank,
Name = "hitwhistle",
Volume = sampleVolume
});
}
if ((soundType & LegacySoundType.Clap) > 0)
{
result.Samples.Add(new SampleInfo
{
Bank = addSampleBank,
Name = "hitclap",
Volume = sampleVolume
});
}
return result;
}
private void readCustomSampleBanks(string str, ref SampleBank normalSampleBank, ref SampleBank addSampleBank)
private void readCustomSampleBanks(string str, ref string normalSampleBank, ref string addSampleBank, ref int sampleVolume)
{
if (string.IsNullOrEmpty(str))
return;
string[] split = str.Split(':');
var sb = (OsuLegacyDecoder.LegacySampleBank)Convert.ToInt32(split[0]);
var addsb = (OsuLegacyDecoder.LegacySampleBank)Convert.ToInt32(split[1]);
int volume = split.Length > 3 ? int.Parse(split[3]) : 0;
var bank = (OsuLegacyDecoder.LegacySampleBank)Convert.ToInt32(split[0]);
var addbank = (OsuLegacyDecoder.LegacySampleBank)Convert.ToInt32(split[1]);
//string sampleFile = split2.Length > 4 ? split2[4] : string.Empty;
normalSampleBank = new SampleBank
{
Name = sb.ToString().ToLower(),
Volume = volume
};
string stringBank = bank.ToString().ToLower();
if (stringBank == @"none")
stringBank = string.Empty;
string stringAddBank = addbank.ToString().ToLower();
if (stringAddBank == @"none")
stringAddBank = string.Empty;
addSampleBank = new SampleBank
{
Name = addsb.ToString().ToLower(),
Volume = volume
};
normalSampleBank = stringBank;
addSampleBank = stringAddBank;
sampleVolume = split.Length > 3 ? int.Parse(split[3]) : 0;
}
[Flags]

View File

@ -71,14 +71,13 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Audio\BeatmapSampleStore.cs" />
<Compile Include="Audio\SampleInfo.cs" />
<Compile Include="Beatmaps\Drawables\BeatmapBackgroundSprite.cs" />
<Compile Include="Beatmaps\DifficultyCalculator.cs" />
<Compile Include="Beatmaps\IBeatmapCoverter.cs" />
<Compile Include="Beatmaps\IBeatmapProcessor.cs" />
<Compile Include="Beatmaps\Legacy\LegacyBeatmap.cs" />
<Compile Include="Beatmaps\Samples\SampleBank.cs" />
<Compile Include="Beatmaps\Samples\Sample.cs" />
<Compile Include="Beatmaps\Samples\SampleType.cs" />
<Compile Include="Beatmaps\Timing\TimeSignatures.cs" />
<Compile Include="Beatmaps\Timing\TimingInfo.cs" />
<Compile Include="Database\ScoreDatabase.cs" />