Skip to content
Open
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
20 changes: 20 additions & 0 deletions RepositoryTuneLab checkout effect
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
f2c6b51 (HEAD -> feature/agent, origin/release/2.0.0, origin/feature/agent, release/2.0.0) Merge branch 'feature/agent' into release/2.0.0
23ce42a refactor: 收紧 agent 工具描述——pitch line 与 vibrato 加性叠加、勿断开音高线
2bbf396 feat: agent 对话分步可见 + 流式实时 Markdown + 取消回复气泡
f8e55db feat: agent 加 add_vibrato 工具(创建真正的 Vibrato 对象)
8a72108 Revert "refactor: effect 收口改订 effect.Modified,退掉 SynthesisBatch band-aid"
f7823b9 fix: OpenAI 兼容流式 tool_call 被后续空 id/name 帧覆盖而丢失
c343b21 feat: agent 工具集三层扩充(只读 / 业务写 / 批量 DSL)
1b4b209 fix: Agent 报错/停止文案可复制——提示行改用 SelectableTextBlock
e64f983 feat: Agent 换模型保上下文 + 连接模型提示 + 标题加固 + 报错保留已输出
0644c43 refactor: effect 收口改订 effect.Modified,退掉 SynthesisBatch band-aid
2d5b708 refactor: ITiming 死契约从 TuneLab.SDK 下沉到宿主 TuneLab.Data.Timing
08e3a84 docs: 订正 plugin-development 的 voice/effect 章节到当前 SDK 模型
74cda39 feat: effect 收敛阶段三——回显富类型换形 + effect 回显端到端
6962336 fix: Agent 短回复时 token 数与 Copy 挤在一起——token 文本加右边距
3576611 refactor: Agent 设置页 provider 选择复用属性面板样式 + 改名 Model Provider
909ced3 feat: Agent 撞工具回合上限时强制收尾——再请求一次不带工具让模型总结
65cbdad fix: DataObject merge 通知上行——中间态不漏成祖先 settled、收口沿父链补发
9a7b359 feat: effect 收敛阶段二——厚 IEffectProcessor/每段一个 + 反应式 EffectGraph
e4e922d feat: Agent 会话菜单 UI 完善——✕ 对齐 + 全名 tooltip + 原生观感
f4e9907 feat: 原子写文件工具 SaveFile(仿 QSaveFile)+ 应用到 agent 写入点
21 changes: 21 additions & 0 deletions TuneLab.SDK/ControllerConfigs/ButtonConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;

namespace TuneLab.SDK;

// 按钮控件配置:在属性面板中渲染一个可点击的按钮。
// 与值控件不同,ButtonConfig 不绑定数据,而是通过 Action 回调触发行为。
// 由宿主侧 PropertyObjectController 的 ButtonCreator 渲染为 GUI Components.Button。
public sealed class ButtonConfig : IControllerConfig
{
/// <summary>按钮显示文本(经 L.Tr 翻译)。</summary>
public required string DisplayText { get; init; }

/// <summary>点击时的回调(在 UI 线程触发)。</summary>
public required Action? Action { get; init; }

/// <summary>按钮激活状态(true=可点击;false=灰显禁用)。</summary>
public bool IsEnabled { get; init; } = true;

/// <summary>按钮提示文字(鼠标悬停时显示)。</summary>
public string? Tooltip { get; init; }
}
45 changes: 45 additions & 0 deletions TuneLab.SDK/ControllerConfigs/PhonemeEditorConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;

namespace TuneLab.SDK;

/// <summary>一个音素条目(含语言前缀与符号)。</summary>
public sealed class PhonemeEntry
{
/// <summary>完整符号,如 "ja/b" 或 "zh/a"。</summary>
public string Symbol { get; set; } = string.Empty;
/// <summary>是否是元音</summary>
public bool IsVowel { get; set; }
/// <summary>是否是滑音</summary>
public bool IsGlide { get; set; }
}

/// <summary>
/// 音素编辑器控件配置:在属性面板中渲染一个可编辑的音素列表(辅音/元音分组)。
/// 数据通过 dataKey 绑定到 PropertyObject 的字符串字段(JSON 格式)。
/// </summary>
public sealed class PhonemeEditorConfig : IControllerConfig
{
public required string DisplayText { get; init; }

/// <summary>在 PropertyObject 中存储音素 JSON 的 key。</summary>
public string DataKey { get; init; } = "_phonemes";

/// <summary>当前音素列表(只读快照,用于 UI 渲染)。</summary>
public IReadOnlyList<PhonemeEntry> Phonemes { get; init; } = Array.Empty<PhonemeEntry>();

/// <summary>可用语言的列表(前缀选项)。</summary>
public IReadOnlyList<string> AvailableLanguages { get; init; } = Array.Empty<string>();

/// <summary>语言属性在 PropertyObject 中的 key。</summary>
public string LanguageDataKey { get; init; } = "language";

/// <summary>添加辅音时的回调(参数:更新后的 JSON)。</summary>
public Action<string>? OnChanged { get; init; }

/// <summary>辅音是否能删除(至少保留一个)。</summary>
public bool CanDeleteConsonant { get; init; } = true;

/// <summary>元音是否能删除(至少保留一个)。</summary>
public bool CanDeleteVowel { get; init; } = true;
}
3 changes: 3 additions & 0 deletions TuneLab.SDK/Voice/IPartPropertyContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ public interface IPartPropertyContext
public interface INotePropertyContext : IPartPropertyContext
{
PropertyObject NoteProperties { get; }
// 当前选中音符的时间范围(用于区段式操作,NaN 表示无选中)
double SelectionStartTime { get; }
double SelectionEndTime { get; }
}
5 changes: 5 additions & 0 deletions TuneLab.SDK/Voice/SynthesizedParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,9 @@ public sealed class SynthesizedParameter
// 各连续段,按时间升序、互不重叠;段内 Points 为 (全局秒, 值) 折线。
// 空集合 = 整条无值;段间间隙 = NaN 区(绘制断开)。
public required IReadOnlyList<IReadOnlyList<Point>> Segments { get; init; }

// 每段的透明度渐变控制点(可选)。每段对应一组 Point,每个 Point 的 X=相对位置(0~1), Y=透明度(0~1)。
// 渲染器据此创建 LinearGradientBrush 的多 GradientStop,实现像素级平滑渐变。
// null = 整段使用默认透明度 0.25。
public IReadOnlyList<IReadOnlyList<Point>>? SegmentOpacityStops { get; init; }
}
2 changes: 1 addition & 1 deletion TuneLab/Data/Synthesis/VoiceSynthesisPipeline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ void WriteBackPhonemes()
}
foreach (var note in mPart.Notes)
{
note.SynthesizedPhonemes = map.TryGetValue(note, out var list) ? list.ToArray() : null;
note.SynthesizedPhonemes = map.TryGetValue(note, out var list) ? list.ToArray() : [];
}
}
catch (Exception ex)
Expand Down
2 changes: 2 additions & 0 deletions TuneLab/GUI/Assets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ internal static class Assets
public static SvgIcon General = new("<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M15.4227 5.07227C15.7799 5.07227 16.1102 5.26287 16.2889 5.57227L19.7117 11.5C19.8902 11.8093 19.8902 12.1907 19.7117 12.5L16.2889 18.4277C16.1102 18.7371 15.7799 18.9277 15.4227 18.9277H8.57697C8.21985 18.9276 7.8903 18.737 7.71173 18.4277L4.28888 12.5C4.11025 12.1906 4.11025 11.8094 4.28888 11.5L7.71173 5.57227C7.8903 5.26298 8.21985 5.0724 8.57697 5.07227H15.4227ZM11.9998 9C10.343 9.0001 8.99982 10.3432 8.99982 12C8.99982 13.6568 10.343 14.9999 11.9998 15C13.6567 15 14.9998 13.6569 14.9998 12C14.9998 10.3431 13.6567 9 11.9998 9Z\" fill=\"white\"/>\n</svg>");
public static SvgIcon Appearance = new("<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M12 21C15 21 11 17 12 15C13.5 12 20 18 20 11.9999C20 5.99985 15.5 3 12 3C8.5 3 4 6 4 11.9999C4 17 8 21 12 21Z\" stroke=\"white\" stroke-width=\"2\" stroke-miterlimit=\"1.01391\" stroke-linejoin=\"round\"/>\n<circle cx=\"8\" cy=\"10.5\" r=\"1.5\" fill=\"white\"/>\n<circle cx=\"10\" cy=\"7.5\" r=\"1.5\" fill=\"white\"/>\n<circle cx=\"14\" cy=\"7.5\" r=\"1.5\" fill=\"white\"/>\n<circle cx=\"16\" cy=\"10.5\" r=\"1.5\" fill=\"white\"/>\n</svg>");
public static SvgIcon Editing = new("<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<rect width=\"16\" height=\"1\" rx=\"0.5\" transform=\"matrix(1 0 0 -1 4 19)\" fill=\"white\"/>\n<path d=\"M16 6C16.6011 6 17.1422 6.20275 17.4697 6.53027C17.8087 6.86923 18.0098 7.41087 18.0078 8.00488C18.0058 8.59988 17.8005 9.13897 17.4697 9.46973L8.68945 18.25H5.75V15.3105L14.5303 6.53027C14.8578 6.20276 15.3989 6 16 6Z\" stroke=\"white\" stroke-width=\"1.5\"/>\n<line x1=\"13.5303\" y1=\"7.46967\" x2=\"16.5303\" y2=\"10.4697\" stroke=\"white\" stroke-width=\"1.5\"/>\n</svg>");
public static SvgIcon PhonemeAdd = new("<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M3 8H13M8 3V13\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>");
public static SvgIcon PhonemeDelete = new("<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M4 8H12\" stroke=\"white\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>");
public static SvgIcon None = new("");

public static FontFamily NotoMono = new FontFamily("NotoMono");
Expand Down
Loading