Skip to content

Commit

Permalink
Merge pull request #38 from AutumnSky1010/feature/#37
Browse files Browse the repository at this point in the history
#37 Provide a method to generate a one-period wave
  • Loading branch information
AutumnSky1010 authored Dec 7, 2024
2 parents 5dca76d + 316c826 commit cd6874d
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 19 deletions.
26 changes: 21 additions & 5 deletions src/SoundMaker/Sounds/WaveTypes/PseudoTriangleWave.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ public override short[] GenerateWave(SoundFormat format, int length, int volume,
}

var result = new List<short>(length);
var unitWave = GenerateUnitWave(format, volume, hertz);
for (var i = 0; i < length / unitWave.Count; i++)
var unitWave = GenerateUnitWaveInternal(format, volume, hertz);
for (var i = 0; i < length / unitWave.Length; i++)
{
result.AddRange(unitWave);
}
for (var i = 0; i < length % unitWave.Count; i++)
for (var i = 0; i < length % unitWave.Length; i++)
{
result.Add(0);
}
Expand All @@ -43,7 +43,23 @@ internal override WaveTypeBase Clone()
return new PseudoTriangleWave();
}

private List<short> GenerateUnitWave(SoundFormat format, int volume, double hertz)
/// <summary>
/// Generates one cycle of a sound waveform at the specified frequency.<br/>
/// 指定した周波数の音声波形1周期分を生成する。
/// </summary>
/// <param name="format">Format of the sound. <br/>音のフォーマット</param>
/// <param name="volume">Volume <br/>音量(0 ~ 100)</param>
/// <param name="hertz">Hertz of the sound. <br/>音の周波数</param>
/// <returns>The array of wave data.</returns>
/// <exception cref="ArgumentOutOfRangeException">Hertz must be non-negative and greater than 0.</exception>
/// <exception cref="ArgumentOutOfRangeException">Volume must be below 100 and above 0.</exception>
public short[] GenerateUnitWave(SoundFormat format, int volume, double hertz)
{
CheckGenerateUnitWaveArgs(volume, hertz);
return GenerateUnitWaveInternal(format, volume, hertz);
}

private static short[] GenerateUnitWaveInternal(SoundFormat format, int volume, double hertz)
{
var repeatNumber = (int)((int)format.SamplingFrequency / hertz);

Expand Down Expand Up @@ -77,6 +93,6 @@ private List<short> GenerateUnitWave(SoundFormat format, int volume, double hert
}
}

return result.ToList();
return result;
}
}
34 changes: 25 additions & 9 deletions src/SoundMaker/Sounds/WaveTypes/SquareWave.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,22 @@ public SquareWave(SquareWaveRatio squareWaveRatio)
/// <summary>
/// デューティ比を基に繰り返し回数を求める為の値
/// </summary>
private List<(double, double)> Ratio { get; } = new List<(double, double)>
{
private static List<(double, double)> Ratio { get; } =
[
(0.875, 0.125),
(0.75, 0.25),
(0.5, 0.5),
};
];

public override short[] GenerateWave(SoundFormat format, int length, int volume, double hertz)
{
var result = new List<short>(length);
var unitWave = GenerateUnitWave(format, volume, hertz);
for (var i = 0; i < length / unitWave.Count; i++)
var unitWave = GenerateUnitWaveInternal(format, volume, hertz, SquareWaveRatio);
for (var i = 0; i < length / unitWave.Length; i++)
{
result.AddRange(unitWave);
}
for (var i = 0; i < length % unitWave.Count; i++)
for (var i = 0; i < length % unitWave.Length; i++)
{
result.Add(0);
}
Expand All @@ -47,9 +47,25 @@ internal override WaveTypeBase Clone()
return new SquareWave(SquareWaveRatio);
}

private List<short> GenerateUnitWave(SoundFormat format, int volume, double hertz)
/// <summary>
/// Generates one cycle of a sound waveform at the specified frequency.<br/>
/// 指定した周波数の音声波形1周期分を生成する。
/// </summary>
/// <param name="format">Format of the sound. <br/>音のフォーマット</param>
/// <param name="volume">Volume <br/>音量(0 ~ 100)</param>
/// <param name="hertz">Hertz of the sound. <br/>音の周波数</param>
/// <returns>The array of wave data.</returns>
/// <exception cref="ArgumentOutOfRangeException">Hertz must be non-negative and greater than 0.</exception>
/// <exception cref="ArgumentOutOfRangeException">Volume must be below 100 and above 0.</exception>
public short[] GenerateUnitWave(SoundFormat format, int volume, double hertz)
{
var ratioIndex = (int)SquareWaveRatio;
CheckGenerateUnitWaveArgs(volume, hertz);
return GenerateUnitWaveInternal(format, volume, hertz, SquareWaveRatio);
}

private static short[] GenerateUnitWaveInternal(SoundFormat format, int volume, double hertz, SquareWaveRatio squareWaveRatio)
{
var ratioIndex = (int)squareWaveRatio;
var allRepeatTimes = (int)((int)format.SamplingFrequency / hertz);
var firstRepeatTimes = (int)(allRepeatTimes * Ratio[ratioIndex].Item1);
// なぜか配列よりリストの方が早い
Expand All @@ -68,6 +84,6 @@ private List<short> GenerateUnitWave(SoundFormat format, int volume, double hert
{
result.Add(bottom);
}
return result;
return result.ToArray();
}
}
26 changes: 21 additions & 5 deletions src/SoundMaker/Sounds/WaveTypes/TriangleWave.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ public override short[] GenerateWave(SoundFormat format, int length, int volume,
{
CheckGenerateWaveArgs(length, volume, hertz);
var result = new List<short>(length);
var unitWave = GenerateUnitWave(format, volume, hertz);
for (var i = 0; i < length / unitWave.Count; i++)
var unitWave = GenerateUnitWaveInternal(format, volume, hertz);
for (var i = 0; i < length / unitWave.Length; i++)
{
result.AddRange(unitWave);
}
for (var i = 0; i < length % unitWave.Count; i++)
for (var i = 0; i < length % unitWave.Length; i++)
{
result.Add(0);
}
Expand All @@ -25,7 +25,23 @@ internal override WaveTypeBase Clone()
return new TriangleWave();
}

private List<short> GenerateUnitWave(SoundFormat format, int volume, double hertz)
/// <summary>
/// Generates one cycle of a sound waveform at the specified frequency.<br/>
/// 指定した周波数の音声波形1周期分を生成する。
/// </summary>
/// <param name="format">Format of the sound. <br/>音のフォーマット</param>
/// <param name="volume">Volume <br/>音量(0 ~ 100)</param>
/// <param name="hertz">Hertz of the sound. <br/>音の周波数</param>
/// <returns>The array of wave data.</returns>
/// <exception cref="ArgumentOutOfRangeException">Hertz must be non-negative and greater than 0.</exception>
/// <exception cref="ArgumentOutOfRangeException">Volume must be below 100 and above 0.</exception>
public short[] GenerateUnitWave(SoundFormat format, int volume, double hertz)
{
CheckGenerateUnitWaveArgs(volume, hertz);
return GenerateUnitWaveInternal(format, volume, hertz);
}

private static short[] GenerateUnitWaveInternal(SoundFormat format, int volume, double hertz)
{
var repeatNumber = (int)((int)format.SamplingFrequency / hertz);

Expand Down Expand Up @@ -58,6 +74,6 @@ private List<short> GenerateUnitWave(SoundFormat format, int volume, double hert
result[halfCount + quarterCount + midOffsetFromHalfCount] = (short)(short.MinValue * volumeMagnification);
}

return result.ToList();
return result;
}
}
6 changes: 6 additions & 0 deletions src/SoundMaker/Sounds/WaveTypes/WaveTypeBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ protected void CheckGenerateWaveArgs(int length, int volume, double hertz)
{
throw new ArgumentOutOfRangeException(nameof(length), "'length' must be non-negative.");
}

CheckGenerateUnitWaveArgs(volume, hertz);
}

protected static void CheckGenerateUnitWaveArgs(int volume, double hertz)
{
if (volume is > 100 or < 0)
{
throw new ArgumentOutOfRangeException(nameof(volume), "'volume must be below than 100 and more than 0.");
Expand Down

0 comments on commit cd6874d

Please sign in to comment.