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.
/// トラックを開始時間に基づいて内部のマップにインポートするメソッド。