diff --git a/src/SoundMaker/Sounds/Score/BasicSoundComponentBase.cs b/src/SoundMaker/Sounds/Score/BasicSoundComponentBase.cs
index 7d786b3..413db69 100644
--- a/src/SoundMaker/Sounds/Score/BasicSoundComponentBase.cs
+++ b/src/SoundMaker/Sounds/Score/BasicSoundComponentBase.cs
@@ -35,6 +35,6 @@ public BasicSoundComponentBase(LengthType length, bool isDotted)
public int GetWaveArrayLength(SoundFormat format, int tempo)
{
- return SoundWaveLengthCalclator.Calclate(format, tempo, Length, IsDotted);
+ return SoundWaveLengthCalculator.Calculate(format, tempo, Length, IsDotted);
}
}
diff --git a/src/SoundMaker/Sounds/Score/SoundWaveLengthCalclator.cs b/src/SoundMaker/Sounds/Score/SoundWaveLengthCalculator.cs
similarity index 92%
rename from src/SoundMaker/Sounds/Score/SoundWaveLengthCalclator.cs
rename to src/SoundMaker/Sounds/Score/SoundWaveLengthCalculator.cs
index b07c16c..0bbe4f4 100644
--- a/src/SoundMaker/Sounds/Score/SoundWaveLengthCalclator.cs
+++ b/src/SoundMaker/Sounds/Score/SoundWaveLengthCalculator.cs
@@ -2,7 +2,7 @@
///
/// 音の配列の長さを計算するクラス
///
-internal static class SoundWaveLengthCalclator
+internal static class SoundWaveLengthCalculator
{
///
/// メソッド。
@@ -13,7 +13,7 @@ internal static class SoundWaveLengthCalclator
/// 付点の場合はTrueに設定する
/// 音の配列の長さ : int
/// Tempo must be non-negative and greater than 0.
- public static int Calclate(SoundFormat format, int tempo, LengthType length, bool isDotted)
+ public static int Calculate(SoundFormat format, int tempo, LengthType length, bool isDotted)
{
if (tempo <= 0)
{
diff --git a/src/SoundMaker/Sounds/Score/Tie.cs b/src/SoundMaker/Sounds/Score/Tie.cs
index 3a21c3f..e4cb7ed 100644
--- a/src/SoundMaker/Sounds/Score/Tie.cs
+++ b/src/SoundMaker/Sounds/Score/Tie.cs
@@ -63,7 +63,7 @@ public int GetWaveArrayLength(SoundFormat format, int tempo)
var length = BaseNote.GetWaveArrayLength(format, tempo);
foreach (var note in AdditionalNotes)
{
- length += SoundWaveLengthCalclator.Calclate(format, tempo, note.Length, note.IsDotted);
+ length += SoundWaveLengthCalculator.Calculate(format, tempo, note.Length, note.IsDotted);
}
return length;
}
diff --git a/src/SoundMaker/Sounds/Score/Tuplet.cs b/src/SoundMaker/Sounds/Score/Tuplet.cs
index 18f2a68..2b96883 100644
--- a/src/SoundMaker/Sounds/Score/Tuplet.cs
+++ b/src/SoundMaker/Sounds/Score/Tuplet.cs
@@ -51,7 +51,7 @@ public Tuplet(IReadOnlyList tupletComponents, LengthType length
public int GetWaveArrayLength(SoundFormat format, int tempo)
{
- return SoundWaveLengthCalclator.Calclate(format, tempo, Length, IsDotted);
+ return SoundWaveLengthCalculator.Calculate(format, tempo, Length, IsDotted);
}
public short[] GenerateWave(SoundFormat format, int tempo, int length, WaveTypeBase waveType)
diff --git a/src/SoundMaker/Sounds/TrackBaseSound.cs b/src/SoundMaker/Sounds/TrackBaseSound.cs
index 14fabd5..d4f3ced 100644
--- a/src/SoundMaker/Sounds/TrackBaseSound.cs
+++ b/src/SoundMaker/Sounds/TrackBaseSound.cs
@@ -219,7 +219,8 @@ public MonauralWave GenerateMonauralWave()
.Where(track => track.Count != 0)
.Max(track => track.EndIndex);
- var wave = new double[maxEndIndex + 1];
+ var wave = new long[maxEndIndex + 1];
+ long maxAmplitude = 0;
foreach (var (_, tracks) in _tracksTimeMap)
{
@@ -234,12 +235,14 @@ public MonauralWave GenerateMonauralWave()
for (int i = track.StartIndex; i <= track.EndIndex; i++)
{
wave[i] += trackWave[i - track.StartIndex];
+ var amplitude = Math.Abs(wave[i]);
+ maxAmplitude = maxAmplitude < amplitude ? amplitude : maxAmplitude;
}
}
}
- var normalizedRight = NormalizeAndClamp(wave);
- return new(normalizedRight);
+ var normalized = NormalizeAndClamp(wave, maxAmplitude);
+ return new(normalized);
}
///
@@ -260,9 +263,11 @@ public StereoWave GenerateStereoWave()
.Where(track => track.Count != 0)
.Max(track => track.EndIndex);
- var right = new double[maxEndIndex + 1];
- var left = new double[maxEndIndex + 1];
+ var right = new long[maxEndIndex + 1];
+ var left = new long[maxEndIndex + 1];
+ long maxAmplitudeRight = 0;
+ long maxAmplitudeLeft = 0;
foreach (var (_, tracks) in _tracksTimeMap)
{
foreach (var track in tracks)
@@ -276,14 +281,19 @@ public StereoWave GenerateStereoWave()
var pan = (track.Pan + 1) / 2.0f;
for (int i = track.StartIndex; i <= track.EndIndex; i++)
{
- left[i] += trackWave[i - track.StartIndex] * pan;
- right[i] += trackWave[i - track.StartIndex] * (1 - pan);
+ left[i] += (long)(trackWave[i - track.StartIndex] * pan);
+ right[i] += (long)(trackWave[i - track.StartIndex] * (1 - pan));
+
+ var amplitudeLeft = Math.Abs(left[i]);
+ var amplitudeRight = Math.Abs(right[i]);
+ maxAmplitudeRight = maxAmplitudeRight < amplitudeRight ? amplitudeRight : maxAmplitudeRight;
+ maxAmplitudeLeft = maxAmplitudeLeft < amplitudeLeft ? amplitudeLeft : maxAmplitudeLeft;
}
}
}
- var normalizedRight = NormalizeAndClamp(right);
- var normalizedLeft = NormalizeAndClamp(left);
+ var normalizedRight = NormalizeAndClamp(right, maxAmplitudeRight);
+ var normalizedLeft = NormalizeAndClamp(left, maxAmplitudeLeft);
return new(normalizedRight, normalizedLeft);
}
@@ -293,26 +303,25 @@ public StereoWave GenerateStereoWave()
///
/// The wave data.
波形データ。
/// The normalized and clamped wave data.
正規化およびクランプされた波形データ。
- private static short[] NormalizeAndClamp(double[] wave)
+ private static short[] NormalizeAndClamp(long[] wave, long maxAmplitude)
{
const int MaxValue = short.MaxValue;
const int MinValue = short.MinValue;
- var maxAmplitude = wave.Max(Math.Abs);
- var scaleFactor = 1.0;
+ var scaleFactor = maxAmplitude > MaxValue ? (double)MaxValue / maxAmplitude : 1.0;
+
+ var normalizedWave = new short[wave.Length];
- if (maxAmplitude > MaxValue)
+ for (int i = 0; i < wave.Length; i++)
{
- scaleFactor = MaxValue / maxAmplitude;
+ var scaledSample = wave[i] * scaleFactor;
+ normalizedWave[i] = (short)Math.Clamp(scaledSample, MinValue, MaxValue);
}
- return wave.Select(sample =>
- {
- var scaledSample = sample * scaleFactor;
- return (short)Math.Clamp(scaledSample, MinValue, MaxValue);
- }).ToArray();
+ return normalizedWave;
}
+
///
/// Imports tracks into the internal map based on their start times.
/// トラックを開始時間に基づいて内部のマップにインポートするメソッド。