Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change TrackBaseSound start milliseconds to start index #40

Merged
merged 3 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 12 additions & 16 deletions src/SoundMaker/Sounds/Track.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ public class Track
/// <param name="waveType">The wave type. <br/> 波形タイプ。</param>
/// <param name="format">The sound format. <br/> サウンドフォーマット。</param>
/// <param name="tempo">The tempo. <br/> テンポ。</param>
/// <param name="startMilliSecond">The start time in milliseconds. <br/> 開始時間(ミリ秒)。</param>
internal Track(WaveTypeBase waveType, SoundFormat format, int tempo, int startMilliSecond)
/// <param name="startIndex">The start time in index. <br/> 開始時間(インデクス)。</param>
internal Track(WaveTypeBase waveType, SoundFormat format, int tempo, int startIndex)
{
WaveType = waveType;
_format = format;
_tempo = tempo;
StartMilliSecond = startMilliSecond;
StartIndex = startIndex;
}


Expand Down Expand Up @@ -58,15 +58,14 @@ public double Pan
}

internal int EndIndex { get; private set; }
internal int StartIndex { get; private set; }
private int _startMilliSecond;
private int _startIndex;
/// <summary>
/// Gets or sets the start time in milliseconds. <br/>
/// 開始時間(ミリ秒)を取得または設定するプロパティ。
/// Gets or sets the start time in index. <br/>
/// 開始時間(インデクス)を取得または設定するプロパティ。
/// </summary>
internal int StartMilliSecond
internal int StartIndex
{
get => _startMilliSecond;
get => _startIndex;
set
{
// 負の数は許可しない
Expand All @@ -75,11 +74,8 @@ internal int StartMilliSecond
value = 0;
}

_startMilliSecond = value;

// 開始ミリ秒が変わると開始時、終了時のインデクスも変わるので、再計算する
var samplingFrequencyMS = (int)_format.SamplingFrequency / 1000.0;
StartIndex = (int)(StartMilliSecond * samplingFrequencyMS);
// 開始インデクスが変わると終了時のインデクスも変わる
_startIndex = value;
if (WaveArrayLength == 0)
{
EndIndex = StartIndex;
Expand All @@ -103,7 +99,7 @@ public int WaveArrayLength
{
_waveArrayLength = value;

// 配列の長さが変わると終了時インデクスが変わるので、再計算する
// 配列の長さが変わると終了時インデクスが変わる
if (WaveArrayLength == 0)
{
EndIndex = StartIndex;
Expand Down Expand Up @@ -245,7 +241,7 @@ public void Import(IEnumerable<ISoundComponent> components)
/// <returns>A new instance of the track with the same properties. <br/> 同じプロパティを持つトラックの新しいインスタンス。</returns>
internal Track Clone()
{
var copy = new Track(WaveType.Clone(), _format, _tempo, StartMilliSecond)
var copy = new Track(WaveType.Clone(), _format, _tempo, StartIndex)
{
WaveArrayLength = WaveArrayLength,
_soundComponents = _soundComponents.Select(component => component.Clone()).ToList()
Expand Down
60 changes: 31 additions & 29 deletions src/SoundMaker/Sounds/TrackBaseSound.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,25 @@ public class TrackBaseSound(SoundFormat format, int tempo)
/// Creates a new track with the specified wave type and start time. <br/>
/// 指定された波の種類と開始時間で新しいトラックを作成するメソッド。
/// </summary>
/// <param name="startMilliSecond">The start time in milliseconds. <br/> 開始時間(ミリ秒)。</param>
/// <param name="startIndex">The start time in index. <br/> 開始時間(インデクス)。</param>
/// <param name="waveType">The type of wave. <br/> 波の種類。</param>
/// <returns>A new instance of the track. <br/> 新しいトラックのインスタンス。</returns>
public Track CreateTrack(int startMilliSecond, WaveTypeBase waveType)
public Track CreateTrack(int startIndex, WaveTypeBase waveType)
{
var track = new Track(waveType, Format, Tempo, startMilliSecond);
InsertTrack(startMilliSecond, track);
var track = new Track(waveType, Format, Tempo, startIndex);
InsertTrack(startIndex, track);
return track;
}

/// <summary>
/// Removes all tracks at the specified start time. <br/>
/// 指定された開始時間のすべてのトラックを削除するメソッド。
/// </summary>
/// <param name="startMilliSecond">The start time in milliseconds. <br/> 開始時間(ミリ秒)。</param>
/// <param name="startIndex">The start time in index. <br/> 開始時間(インデクス)。</param>
/// <returns>True if tracks were removed; otherwise, false. <br/> トラックが削除された場合は true、それ以外の場合は false。</returns>
public bool RemoveTracksAt(int startMilliSecond)
public bool RemoveTracksAt(int startIndex)
{
return _tracksTimeMap.Remove(startMilliSecond);
return _tracksTimeMap.Remove(startIndex);
}

/// <summary>
Expand All @@ -65,7 +65,7 @@ public bool RemoveTracksAt(int startMilliSecond)
/// <returns>True if the track was removed; otherwise, false. <br/> トラックが削除された場合は true、それ以外の場合は false。</returns>
public bool RemoveTrack(Track track)
{
if (_tracksTimeMap.TryGetValue(track.StartMilliSecond, out var tracks))
if (_tracksTimeMap.TryGetValue(track.StartIndex, out var tracks))
{
var ok = tracks.Remove(track);
if (!ok)
Expand All @@ -75,7 +75,7 @@ public bool RemoveTrack(Track track)

if (tracks.Count == 0)
{
return _tracksTimeMap.Remove(track.StartMilliSecond);
return _tracksTimeMap.Remove(track.StartIndex);
}

return true;
Expand All @@ -88,17 +88,17 @@ public bool RemoveTrack(Track track)
/// Gets the list of tracks at the specified start time. <br/>
/// 指定された開始時間のトラックのリストを取得するメソッド。
/// </summary>
/// <param name="startMilliSecond">The start time in milliseconds. <br/> 開始時間(ミリ秒)。</param>
/// <param name="startIndex">The start time in index. <br/> 開始時間(インデクス)。</param>
/// <returns>
/// A list of tracks. <br/>
/// トラックのリスト。
/// If the operation fails, an empty list is returned. <br/>
/// 失敗時は空リスト。
/// </returns>

public List<Track> GetTracks(int startMilliSecond)
public List<Track> GetTracks(int startIndex)
{
if (_tracksTimeMap.TryGetValue(startMilliSecond, out var tracks))
if (_tracksTimeMap.TryGetValue(startIndex, out var tracks))
{
return tracks;
}
Expand All @@ -124,12 +124,12 @@ public IEnumerable<Track> GetAllTracks()
/// Tries to get the list of tracks at the specified start time. <br/>
/// 指定された開始時間のトラックのリストを取得しようとするメソッド。
/// </summary>
/// <param name="startMilliSecond">The start time in milliseconds. <br/> 開始時間(ミリ秒)。</param>
/// <param name="startIndex">The start time in index. <br/> 開始時間(インデクス)。</param>
/// <param name="tracks">The list of tracks. <br/> トラックのリスト。</param>
/// <returns>True if tracks were found; otherwise, false. <br/> トラックが見つかった場合は true、それ以外の場合は false。</returns>
public bool TryGetTracks(int startMilliSecond, out List<Track> tracks)
public bool TryGetTracks(int startIndex, out List<Track> tracks)
{
if (_tracksTimeMap.TryGetValue(startMilliSecond, out var foundTracks))
if (_tracksTimeMap.TryGetValue(startIndex, out var foundTracks))
{
tracks = foundTracks;
return true;
Expand All @@ -145,17 +145,17 @@ public bool TryGetTracks(int startMilliSecond, out List<Track> tracks)
/// Inserts a track at the specified start time. <br/>
/// 指定された開始時間にトラックを挿入するメソッド。
/// </summary>
/// <param name="startMilliSecond">The start time in milliseconds. <br/> 開始時間(ミリ秒)。</param>
/// <param name="startIndex">The start time in index. <br/> 開始時間(インデクス)。</param>
/// <param name="track">The track to insert. <br/> 挿入するトラック。</param>
private void InsertTrack(int startMilliSecond, Track track)
private void InsertTrack(int startIndex, Track track)
{
if (_tracksTimeMap.TryGetValue(startMilliSecond, out var tracks))
if (_tracksTimeMap.TryGetValue(startIndex, out var tracks))
{
tracks.Add(track);
}
else
{
_tracksTimeMap[startMilliSecond] = [track];
_tracksTimeMap[startIndex] = [track];
}
}

Expand All @@ -164,14 +164,14 @@ private void InsertTrack(int startMilliSecond, Track track)
/// トラックを新しい開始時間に移動するメソッド。
/// </summary>
/// <param name="track">The track to move. <br/> 移動するトラック。</param>
/// <param name="newStartMilliSecond">The new start time in milliseconds. <br/> 新しい開始時間(ミリ秒)。</param>
/// <param name="newStartIndex">The new start time in index. <br/> 新しい開始時間(インデクス)。</param>
/// <returns>True if the track was moved; otherwise, false. <br/> トラックが移動された場合は true、それ以外の場合は false。</returns>
public bool MoveTrack(Track track, int newStartMilliSecond)
public bool MoveTrack(Track track, int newStartIndex)
{
if (RemoveTrack(track))
{
InsertTrack(newStartMilliSecond, track);
track.StartMilliSecond = newStartMilliSecond;
InsertTrack(newStartIndex, track);
track.StartIndex = newStartIndex;
return true;
}
return false;
Expand All @@ -182,13 +182,13 @@ public bool MoveTrack(Track track, int newStartMilliSecond)
/// 指定されたトラックのコピーを新しい開始時間に作成するメソッド。
/// </summary>
/// <param name="sourceTrack">The track to copy. <br/> コピーするトラック。</param>
/// <param name="newStartMilliSecond">The new start time in milliseconds. <br/> 新しい開始時間(ミリ秒)。</param>
/// <param name="newStartIndex">The new start time in index. <br/> 新しい開始時間(インデクス)。</param>
/// <returns>A new instance of the copied track. <br/> コピーされたトラックの新しいインスタンス。</returns>
public Track CopyTrack(Track sourceTrack, int newStartMilliSecond)
public Track CopyTrack(Track sourceTrack, int newStartIndex)
{
var newTrack = sourceTrack.Clone();
newTrack.StartMilliSecond = newStartMilliSecond;
InsertTrack(newStartMilliSecond, newTrack);
newTrack.StartIndex = newStartIndex;
InsertTrack(newStartIndex, newTrack);
return newTrack;
}

Expand Down Expand Up @@ -216,6 +216,7 @@ public MonauralWave GenerateMonauralWave()
// 最大の終了時インデクスを取得する
var maxEndIndex = _tracksTimeMap
.SelectMany(pair => pair.Value)
.Where(track => track.Count != 0)
.Max(track => track.EndIndex);

var wave = new double[maxEndIndex + 1];
Expand Down Expand Up @@ -256,6 +257,7 @@ public StereoWave GenerateStereoWave()
// 最大の終了時インデクスを取得する
var maxEndIndex = _tracksTimeMap
.SelectMany(pair => pair.Value)
.Where(track => track.Count != 0)
.Max(track => track.EndIndex);

var right = new double[maxEndIndex + 1];
Expand Down Expand Up @@ -321,13 +323,13 @@ public void Import(IEnumerable<Track> from)
var map = new Dictionary<int, List<Track>>();
foreach (var track in from)
{
if (map.TryGetValue(track.StartMilliSecond, out var tracks))
if (map.TryGetValue(track.StartIndex, out var tracks))
{
tracks.Add(track);
}
else
{
map.Add(track.StartMilliSecond, [track]);
map.Add(track.StartIndex, [track]);
}
}

Expand Down
14 changes: 7 additions & 7 deletions test/UnitTests/Sounds/TrackBaseSoundTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ public void GetAllTracks()
Assert.True(track2.Equals(actual[1]));
}

[Fact(DisplayName = "指定したミリ秒から開始するトラックをすべて削除できるか")]
[Fact(DisplayName = "指定したインデクスから開始するトラックをすべて削除できるか")]
public void RemoveTracksAt()
{
var format = FormatBuilder.Create()
.WithFrequency(44100)
.WithBitDepth(8)
.WithChannelCount(1)
.ToSoundFormat();
// 0ミリ秒開始のトラックを削除する対象とする
// 0インデクス開始のトラックを削除する対象とする
var targetStartMS = 0;
var sound = new TrackBaseSound(format, 100);
var wave = new SquareWave(SquareWaveRatio.Point25);
Expand Down Expand Up @@ -73,7 +73,7 @@ public void RemoveTrack()
Assert.False(maybeFail);
}

[Fact(DisplayName = "指定したミリ秒から開始するトラックをすべて取得できるか")]
[Fact(DisplayName = "指定したインデクスから開始するトラックをすべて取得できるか")]
public void GetTracks()
{
var format = FormatBuilder.Create()
Expand All @@ -85,7 +85,7 @@ public void GetTracks()
var wave = new SquareWave(SquareWaveRatio.Point25);
var track1 = sound.CreateTrack(0, wave);

var tracks = sound.GetTracks(track1.StartMilliSecond);
var tracks = sound.GetTracks(track1.StartIndex);
Assert.Contains(track1, tracks);
}

Expand Down Expand Up @@ -116,7 +116,7 @@ public void TryGetTracks()
var wave = new SquareWave(SquareWaveRatio.Point25);
var track1 = sound.CreateTrack(0, wave);

Assert.True(sound.TryGetTracks(track1.StartMilliSecond, out var tracks));
Assert.True(sound.TryGetTracks(track1.StartIndex, out var tracks));
Assert.Contains(track1, tracks);

Assert.False(sound.TryGetTracks(1000, out _));
Expand All @@ -135,8 +135,8 @@ public void Insert()
var track1 = sound.CreateTrack(0, wave);
var track2 = sound.CreateTrack(1000, wave);

Assert.Equal(track1, sound.GetTracks(track1.StartMilliSecond)[0]);
Assert.Equal(track2, sound.GetTracks(track2.StartMilliSecond)[0]);
Assert.Equal(track1, sound.GetTracks(track1.StartIndex)[0]);
Assert.Equal(track2, sound.GetTracks(track2.StartIndex)[0]);
}

[Fact(DisplayName = "トラックの移動を行えるか")]
Expand Down
14 changes: 7 additions & 7 deletions test/UnitTests/Sounds/TrackTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace SoundMakerTests.UnitTests.Sounds;

file class SoundComponentDouble : ISoundComponent
{
public static readonly int DefinedGenerateWaveLength = 1;
public static readonly int DefinedGenerateWaveLength = 2;

public ISoundComponent Clone()
{
Expand All @@ -21,7 +21,7 @@ public short[] GenerateWave(SoundFormat format, int tempo, int length, WaveTypeB

public short[] GenerateWave(SoundFormat format, int tempo, WaveTypeBase waveType)
{
return [0];
return [0, 1];
}

public int GetWaveArrayLength(SoundFormat format, int tempo)
Expand Down Expand Up @@ -138,14 +138,14 @@ public void Clear()
}

[Fact(DisplayName = "開始位置を変更した際にインデクス関連のプロパティが正しく変更されるか")]
public void ChangeStartMilliSecond()
public void ChangeStartIndex()
{
var track = CreateTrack();
var oldStartIndex = track.StartIndex;
var oldEndIndex = track.EndIndex;
var diffIndex = _samplingFrequency;
// 1000ミリ秒減らす
track.StartMilliSecond -= 1000;
var diffIndex = 1;
// 1減らす
track.StartIndex -= diffIndex;

var expectedEndIndex = oldEndIndex - diffIndex;
Assert.Equal(expectedEndIndex, track.EndIndex);
Expand All @@ -158,7 +158,7 @@ private Track CreateTrack()
.WithBitDepth(16)
.WithChannelCount(2)
.ToSoundFormat();
return new Track(new TriangleWave(), format, 100, 1000);
return new Track(new TriangleWave(), format, 100, 1);
}

private void AssertEndIndex(Track track)
Expand Down
Loading