Skip to content

Commit

Permalink
feat: 音频文件使用相对路径存储
Browse files Browse the repository at this point in the history
  • Loading branch information
LiuYunPlayer committed Dec 21, 2024
1 parent 2d44dc3 commit 3df08c8
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 40 deletions.
100 changes: 61 additions & 39 deletions TuneLab/Data/AudioPart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace TuneLab.Data;
internal class AudioPart : Part, IAudioPart
{
public IActionEvent AudioChanged => mAudioChanged;
public INotifiableProperty<string> BaseDirectory { get; } = new NotifiableProperty<string>(string.Empty);
public override DataString Name { get; }
public override DataStruct<double> Pos { get; }
public override DataStruct<double> Dur { get; }
Expand All @@ -27,56 +28,32 @@ public AudioPart(ITrack track, AudioPartInfo info) : base(track)
Dur = new(this);
Path = new(this, string.Empty);
Dur.Modified.Subscribe(mDurationChanged);
Path.Modified.Subscribe(async () =>
{
mAudioData = null;
mWaveforms = [];
mAudioChanged.Invoke();
IAudioData? audioData = null;
Waveform[]? waveforms = null;
await Task.Run(() =>
{
try
{
int samplingRate = AudioEngine.SamplingRate;
var data = AudioUtils.Decode(Path, ref samplingRate);
switch (data.Length)
{
case 1:
audioData = new MonoAudioData(data[0]);
waveforms = [new(data[0])];
break;
case 2:
audioData = new StereoAudioData(data[0], data[1]);
waveforms = [new(data[0]), new(data[1])];
break;
}
}
catch (Exception ex)
{
audioData = null;
waveforms = null;
}
});

if (audioData == null || waveforms == null)
return;

mAudioData = audioData;
mWaveforms = waveforms;
mAudioChanged.Invoke();
Path.Modified.Subscribe(Reload);
BaseDirectory.Modified.Subscribe(() =>
{
if (Path.Value.StartsWith(".."))
Reload();
});
IDataObject<AudioPartInfo>.SetInfo(this, info);
}

public override AudioPartInfo GetInfo()
{
var path = Path.Value;
if (!string.IsNullOrEmpty(BaseDirectory.Value))
{
if (path.StartsWith(BaseDirectory.Value))
{
path = ".." + path[BaseDirectory.Value.Length..];
}
}

return new()
{
Name = Name,
Pos = Pos,
Dur = Dur,
Path = Path
Path = path
};
}

Expand Down Expand Up @@ -106,6 +83,51 @@ protected override int SampleCount()
return mAudioData == null ? 0 : Math.Min(base.SampleCount(), mAudioData.Count);
}

async void Reload()
{
mAudioData = null;
mWaveforms = [];
mAudioChanged.Invoke();
IAudioData? audioData = null;
Waveform[]? waveforms = null;
await Task.Run(() =>
{
try
{
string path = Path;
if (path.StartsWith(".."))
{
path = System.IO.Path.Combine(BaseDirectory.Value, path[3..]);
}
int samplingRate = AudioEngine.SamplingRate;
var data = AudioUtils.Decode(path, ref samplingRate);
switch (data.Length)
{
case 1:
audioData = new MonoAudioData(data[0]);
waveforms = [new(data[0])];
break;
case 2:
audioData = new StereoAudioData(data[0], data[1]);
waveforms = [new(data[0]), new(data[1])];
break;
}
}
catch (Exception ex)
{
audioData = null;
waveforms = null;
}
});

if (audioData == null || waveforms == null)
return;

mAudioData = audioData;
mWaveforms = waveforms;
mAudioChanged.Invoke();
}

protected override int SamplingRate => AudioEngine.SamplingRate;
public int ChannelCount => mWaveforms.Length;

Expand Down
1 change: 1 addition & 0 deletions TuneLab/Data/IAudioPart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace TuneLab.Data;
internal interface IAudioPart : IPart, IDataObject<AudioPartInfo>
{
IActionEvent AudioChanged { get; }
INotifiableProperty<string> BaseDirectory { get; }
IDataProperty<string> Path { get; }
int ChannelCount { get; }
Waveform GetWaveform(int channelIndex);
Expand Down
50 changes: 49 additions & 1 deletion TuneLab/Data/ProjectDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,71 @@ public ProjectDocument()
{
Project?.Attach(this);
});

mProject.When(project => project.Tracks.ItemAdded).Subscribe(track =>
{
var dir = AudioPartBaseDirectory();
if (string.IsNullOrEmpty(dir))
return;

foreach (var audioPart in track.Parts.OfType<IAudioPart>())
{
audioPart.BaseDirectory.Value = dir;
}
});

mProject.When(project => project.Tracks.Any(track => track.Parts.ItemAdded)).Subscribe(part =>
{
if (part is not IAudioPart audioPart)
return;

var dir = AudioPartBaseDirectory();
if (string.IsNullOrEmpty(dir))
return;

audioPart.BaseDirectory.Value = dir;
});
}

public void SetProject(Project project, string path = "")
{
Clear();
SetSavePath(path);
mProject.Set(project);
SetSavePath(path);
}

public void SetSavePath(string path)
{
mPath = path;
ResetAudioPartBaseDirectory();
mName = File.Exists(path) ? new FileInfo(path).Name : "Untitled Project".Tr(TC.Document);
mLastSavedHead = Head;
mProjectNameChanged?.Invoke();
}

string? AudioPartBaseDirectory()
{
if (Project == null)
return null;

return System.IO.Path.GetDirectoryName(mPath);
}

void ResetAudioPartBaseDirectory()
{
if (Project == null)
return;

var dir = AudioPartBaseDirectory();
if (string.IsNullOrEmpty(dir))
return;

foreach (var audioPart in Project.AllAudioParts())
{
audioPart.BaseDirectory.Value = dir;
}
}

string mPath = string.Empty;
string mName = string.Empty;
Head mLastSavedHead;
Expand Down

0 comments on commit 3df08c8

Please sign in to comment.