Fix Preset Save

This commit is contained in:
copecone committed 2026-07-25 08:18:27 +09:00
1 parent 8bc855db41
commit c07b57b273
5 files changed
+79 -70

No files matched your search

+11 -11
View File
@@ -387,9 +387,9 @@ namespace ADOFAIRenderer.Core
private IEnumerator SetupPlay() private IEnumerator SetupPlay()
{ {
if (Configuration.RenderAudio && GetOutputExtension(Configuration.VideoConfig!.Codec) != ".mp4") if (Configuration.AudioConfig.RenderAudio && GetOutputExtension(Configuration.VideoConfig!.Codec) != ".mp4")
{ {
Configuration.AudioSampleRate = 48000; Configuration.AudioConfig.AudioSampleRate = 48000;
} }
for (; countdown > 0; countdown--) for (; countdown > 0; countdown--)
@@ -435,13 +435,13 @@ namespace ADOFAIRenderer.Core
AudioSpectrumGenerator.Initialize(scrConductor.instance.song.clip); AudioSpectrumGenerator.Initialize(scrConductor.instance.song.clip);
} }
if (Configuration.RenderAudio) if (Configuration.AudioConfig.RenderAudio)
{ {
AudioMixer = new OfflineAudioMixer(Configuration.AudioChannels, Configuration.AudioSampleRate); AudioMixer = new OfflineAudioMixer(Configuration.AudioConfig.AudioChannels, Configuration.AudioConfig.AudioSampleRate);
AudioMixer.InitializeBGM(scrConductor.instance.song.clip); AudioMixer.InitializeBGM(scrConductor.instance.song.clip);
var effectiveVideoFps = Math.Min(Configuration.VideoFPS, Configuration.RenderFPS); var effectiveVideoFps = Math.Min(Configuration.VideoFPS, Configuration.RenderFPS);
SyncCalculator = new AudioSyncCalculator(Configuration.AudioSampleRate, effectiveVideoFps); SyncCalculator = new AudioSyncCalculator(Configuration.AudioConfig.AudioSampleRate, effectiveVideoFps);
} }
scrConductor.instance.song.clip = null; scrConductor.instance.song.clip = null;
@@ -499,13 +499,13 @@ namespace ADOFAIRenderer.Core
MaxBitrate = Configuration.VideoConfig.MaxBitrate, MaxBitrate = Configuration.VideoConfig.MaxBitrate,
GopSize = Configuration.VideoConfig.KeyframeInterval, GopSize = Configuration.VideoConfig.KeyframeInterval,
ForceSoftware = Configuration.VideoConfig.ForceSoftwareEncoder, ForceSoftware = Configuration.VideoConfig.ForceSoftwareEncoder,
Audio = Configuration.RenderAudio ? new FFmpegNativeEncoder.AudioSettings Audio = Configuration.AudioConfig.RenderAudio ? new FFmpegNativeEncoder.AudioSettings
{ {
SampleRate = Configuration.AudioSampleRate, SampleRate = Configuration.AudioConfig.AudioSampleRate,
Channels = Configuration.AudioChannels, Channels = Configuration.AudioConfig.AudioChannels,
InputSampleFormat = AVSampleFormat.AV_SAMPLE_FMT_FLT, InputSampleFormat = AVSampleFormat.AV_SAMPLE_FMT_FLT,
AudioCodecId = codecId, AudioCodecId = codecId,
Bitrate = Configuration.AudioBitrate Bitrate = Configuration.AudioConfig.AudioBitrate
} : null } : null
}; };
@@ -586,13 +586,13 @@ namespace ADOFAIRenderer.Core
} }
} }
if (Configuration.RenderAudio) if (Configuration.AudioConfig.RenderAudio)
{ {
var frameIdx = (int)(passCount - 1); var frameIdx = (int)(passCount - 1);
var effectiveVideoFps = Math.Min(Configuration.VideoFPS, Configuration.RenderFPS); var effectiveVideoFps = Math.Min(Configuration.VideoFPS, Configuration.RenderFPS);
var frameTime = frameIdx / effectiveVideoFps; var frameTime = frameIdx / effectiveVideoFps;
var channels = Configuration.AudioChannels; var channels = Configuration.AudioConfig.AudioChannels;
var samplesNeeded = SyncCalculator.GetNextFrameSamples(); var samplesNeeded = SyncCalculator.GetNextFrameSamples();
var audioBuffer = ArrayPool<float>.Shared.Rent(samplesNeeded * channels); var audioBuffer = ArrayPool<float>.Shared.Rent(samplesNeeded * channels);
+20 -15
View File
@@ -84,9 +84,9 @@ namespace ADOFAIRenderer.Data
// 2. legacy top-level Codec -> VideoConfig.Codec // 2. legacy top-level Codec -> VideoConfig.Codec
var legacyCodecToken = configObj["Codec"]; var legacyCodecToken = configObj["Codec"];
if (legacyCodecToken != null) if (legacyCodecToken != null && legacyCodecToken.Type != JTokenType.Null)
{ {
if (configObj["VideoConfig"] == null) if (configObj["VideoConfig"] == null || configObj["VideoConfig"]!.Type == JTokenType.Null)
{ {
configObj["VideoConfig"] = new JObject(); configObj["VideoConfig"] = new JObject();
} }
@@ -98,22 +98,27 @@ namespace ADOFAIRenderer.Data
} }
// 3. legacy top-level Audio properties -> AudioConfig // 3. legacy top-level Audio properties -> AudioConfig
if (configObj["AudioConfig"] == null) string[] legacyAudioProps = { "RenderAudio", "AudioSampleRate", "AudioChannels", "AudioBitrate" };
foreach (var prop in legacyAudioProps)
{ {
var audioConfigObj = new JObject(); var legacyToken = configObj[prop];
if (configObj["RenderAudio"] != null) if (legacyToken != null && legacyToken.Type != JTokenType.Null)
audioConfigObj["RenderAudio"] = configObj["RenderAudio"];
if (configObj["AudioSampleRate"] != null)
audioConfigObj["AudioSampleRate"] = configObj["AudioSampleRate"];
if (configObj["AudioChannels"] != null)
audioConfigObj["AudioChannels"] = configObj["AudioChannels"];
if (configObj["AudioBitrate"] != null)
audioConfigObj["AudioBitrate"] = configObj["AudioBitrate"];
if (audioConfigObj.HasValues)
{ {
configObj["AudioConfig"] = audioConfigObj; if (configObj["AudioConfig"] == null || configObj["AudioConfig"]!.Type == JTokenType.Null)
{
configObj["AudioConfig"] = new JObject();
} }
var audioConfigObj = (JObject)configObj["AudioConfig"]!;
audioConfigObj[prop] ??= legacyToken;
}
configObj.Remove(prop);
}
if (configObj["AudioConfig"] != null && configObj["AudioConfig"]!.Type == JTokenType.Null)
{
configObj.Remove("AudioConfig");
} }
} }
+30 -36
View File
@@ -10,59 +10,53 @@ namespace ADOFAIRenderer.Data
public int RenderWidth { get; set; } public int RenderWidth { get; set; }
public int RenderHeight { get; set; } public int RenderHeight { get; set; }
public VideoEncodingConfig? VideoConfig { get; set; } public VideoEncodingConfig VideoConfig { get; set; } = new VideoEncodingConfig();
public AudioEncodingConfig? AudioConfig { get; set; } public AudioEncodingConfig AudioConfig { get; set; } = new AudioEncodingConfig();
public double DelayAfterLevelEnd { get; set; } public double DelayAfterLevelEnd { get; set; }
public bool ShowJudgementText { get; set; } public bool ShowJudgementText { get; set; }
public int? RandomSeed { get; set; } = null; public int? RandomSeed { get; set; } = null;
public bool ProcessAudio { get; set; } public bool ProcessAudio { get; set; }
// 하위 호환 및 편의를 위한 접근자
public bool RenderAudio
{
get => AudioConfig?.RenderAudio ?? true;
set => (AudioConfig ??= new AudioEncodingConfig()).RenderAudio = value;
}
public int AudioSampleRate
{
get => AudioConfig?.AudioSampleRate ?? 44100;
set { (AudioConfig ??= new AudioEncodingConfig()).AudioSampleRate = value; }
}
public int AudioChannels
{
get => AudioConfig?.AudioChannels ?? 2;
set { (AudioConfig ??= new AudioEncodingConfig()).AudioChannels = value; }
}
public int AudioBitrate
{
get => AudioConfig?.AudioBitrate ?? 256000;
set { (AudioConfig ??= new AudioEncodingConfig()).AudioBitrate = value; }
}
} }
public class VideoEncodingConfig public class VideoEncodingConfig
{ {
public Codec Codec { get; set; } = Codec.H264; public Codec Codec { get; set; } = Codec.H264;
public RateControlMode RateControlMode { get; set; } public RateControlMode RateControlMode { get; set; } = RateControlMode.CBR;
public int Bitrate { get; set; } public int Bitrate { get; set; } = 30000;
public int MaxBitrate { get; set; } public int MaxBitrate { get; set; } = 50000;
// ReSharper disable once InconsistentNaming // ReSharper disable once InconsistentNaming
public int QP { get; set; } public int QP { get; set; } = 18;
public double KeyframeInterval { get; set; } public double KeyframeInterval { get; set; } = 2.0;
public bool ForceSoftwareEncoder { get; set; } public bool ForceSoftwareEncoder { get; set; } = false;
} }
public class AudioEncodingConfig public class AudioEncodingConfig
{ {
private int _audioSampleRate = 44100;
private int _audioChannels = 2;
private int _audioBitrate = 256000;
public bool RenderAudio { get; set; } = true; public bool RenderAudio { get; set; } = true;
public int AudioSampleRate { get; set; } = 44100;
public int AudioChannels { get; set; } = 2; public int AudioSampleRate
public int AudioBitrate { get; set; } = 256000; {
get => _audioSampleRate <= 0 ? 44100 : _audioSampleRate;
set => _audioSampleRate = value <= 0 ? 44100 : value;
}
public int AudioChannels
{
get => _audioChannels <= 0 ? 2 : _audioChannels;
set => _audioChannels = value <= 0 ? 2 : value;
}
public int AudioBitrate
{
get => _audioBitrate <= 0 ? 256000 : _audioBitrate;
set => _audioBitrate = value <= 0 ? 256000 : value;
}
} }
} }
+6 -6
View File
@@ -12,7 +12,7 @@ namespace ADOFAIRenderer.Patch.Engine
[HarmonyPrefix] [HarmonyPrefix]
public static bool Prefix(string snd, double time, AudioMixerGroup group, float volume, int priority) public static bool Prefix(string snd, double time, AudioMixerGroup group, float volume, int priority)
{ {
if (RenderManager.IsCapturingActive && RenderManager.Instance.Configuration.RenderAudio) if (RenderManager.IsCapturingActive && RenderManager.Instance.Configuration.AudioConfig.RenderAudio)
{ {
// Cache the clip on the main thread // Cache the clip on the main thread
RenderManager.Instance.AudioMixer?.CacheClip(snd); RenderManager.Instance.AudioMixer?.CacheClip(snd);
@@ -23,7 +23,7 @@ namespace ADOFAIRenderer.Patch.Engine
[HarmonyPostfix] [HarmonyPostfix]
public static void Postfix(AudioSource __result, string snd, double time, AudioMixerGroup group, float volume, int priority) public static void Postfix(AudioSource __result, string snd, double time, AudioMixerGroup group, float volume, int priority)
{ {
if (RenderManager.IsCapturingActive && RenderManager.Instance.Configuration.RenderAudio && __result != null) if (RenderManager.IsCapturingActive && RenderManager.Instance.Configuration.AudioConfig.RenderAudio && __result != null)
{ {
// Convert absolute DSP time to relative time in seconds from render start // Convert absolute DSP time to relative time in seconds from render start
double relativeStartTime = time - RenderManager.Instance.dspTimeBase; double relativeStartTime = time - RenderManager.Instance.dspTimeBase;
@@ -40,7 +40,7 @@ namespace ADOFAIRenderer.Patch.Engine
[HarmonyPrefix] [HarmonyPrefix]
public static bool Prefix(string snd, double time, double endTime, float volume, int priority) public static bool Prefix(string snd, double time, double endTime, float volume, int priority)
{ {
if (RenderManager.IsCapturingActive && RenderManager.Instance.Configuration.RenderAudio) if (RenderManager.IsCapturingActive && RenderManager.Instance.Configuration.AudioConfig.RenderAudio)
{ {
var mixer = RenderManager.Instance.AudioMixer; var mixer = RenderManager.Instance.AudioMixer;
if (mixer != null) if (mixer != null)
@@ -67,7 +67,7 @@ namespace ADOFAIRenderer.Patch.Engine
// ReSharper disable once InconsistentNaming // ReSharper disable once InconsistentNaming
public static void Postfix(AudioSource __instance, float value) public static void Postfix(AudioSource __instance, float value)
{ {
if (RenderManager.IsCapturingActive && RenderManager.Instance.Configuration.RenderAudio) if (RenderManager.IsCapturingActive && RenderManager.Instance.Configuration.AudioConfig.RenderAudio)
{ {
var mixer = RenderManager.Instance.AudioMixer; var mixer = RenderManager.Instance.AudioMixer;
if (mixer != null && mixer.TryGetSoundEvent(__instance, out var soundEvent)) if (mixer != null && mixer.TryGetSoundEvent(__instance, out var soundEvent))
@@ -86,7 +86,7 @@ namespace ADOFAIRenderer.Patch.Engine
[HarmonyPostfix] [HarmonyPostfix]
public static void Postfix(AudioSource __instance, double time) public static void Postfix(AudioSource __instance, double time)
{ {
if (RenderManager.IsCapturingActive && RenderManager.Instance.Configuration.RenderAudio) if (RenderManager.IsCapturingActive && RenderManager.Instance.Configuration.AudioConfig.RenderAudio)
{ {
var mixer = RenderManager.Instance.AudioMixer; var mixer = RenderManager.Instance.AudioMixer;
if (mixer != null && mixer.TryGetSoundEvent(__instance, out var soundEvent)) if (mixer != null && mixer.TryGetSoundEvent(__instance, out var soundEvent))
@@ -103,7 +103,7 @@ namespace ADOFAIRenderer.Patch.Engine
[HarmonyPostfix] [HarmonyPostfix]
public static void Postfix(AudioSource __instance) public static void Postfix(AudioSource __instance)
{ {
if (RenderManager.IsCapturingActive && RenderManager.Instance.Configuration.RenderAudio) if (RenderManager.IsCapturingActive && RenderManager.Instance.Configuration.AudioConfig.RenderAudio)
{ {
RenderManager.Instance.AudioMixer?.RemoveSourceMapping(__instance); RenderManager.Instance.AudioMixer?.RemoveSourceMapping(__instance);
} }
+12 -2
View File
@@ -327,7 +327,7 @@ namespace ADOFAIRenderer.UI
AudioBitrate = config.AudioConfig.AudioBitrate AudioBitrate = config.AudioConfig.AudioBitrate
}; };
if (_root.Contains(_audioEncodingConfigContainer)) if (_audioEncodingConfigContainer != null && _root.Contains(_audioEncodingConfigContainer))
{ {
_root.Remove(_audioEncodingConfigContainer); _root.Remove(_audioEncodingConfigContainer);
} }
@@ -372,9 +372,14 @@ namespace ADOFAIRenderer.UI
// 3. 샘플 레이트 로우 // 3. 샘플 레이트 로우
var sampleRateRow = CreateRow(); var sampleRateRow = CreateRow();
var sampleRateLabel = CreateFormLabel("샘플 레이트(Hz)"); var sampleRateLabel = CreateFormLabel("샘플 레이트(Hz)");
var sampleRateStr = tempAudioConfig.AudioSampleRate.ToString();
if (sampleRateStr != "44100" && sampleRateStr != "48000")
{
sampleRateStr = "44100";
}
var sampleRateDropdown = new DropdownField( var sampleRateDropdown = new DropdownField(
new List<string> { "44100", "48000" }, new List<string> { "44100", "48000" },
tempAudioConfig.AudioSampleRate.ToString() sampleRateStr
); );
sampleRateRow.Add(sampleRateLabel); sampleRateRow.Add(sampleRateLabel);
sampleRateRow.Add(sampleRateDropdown); sampleRateRow.Add(sampleRateDropdown);
@@ -498,6 +503,7 @@ namespace ADOFAIRenderer.UI
config.RandomSeed = null; config.RandomSeed = null;
RenderManager.Instance.Configuration.VideoConfig ??= GenerateEncodingConfig(); RenderManager.Instance.Configuration.VideoConfig ??= GenerateEncodingConfig();
RenderManager.Instance.Configuration.AudioConfig ??= GenerateAudioEncodingConfig();
RenderManager.Instance.SetupCaptureDirectory(); RenderManager.Instance.SetupCaptureDirectory();
RenderManager.Instance.SetupGameScene(); RenderManager.Instance.SetupGameScene();
@@ -569,6 +575,9 @@ namespace ADOFAIRenderer.UI
} }
} }
config.VideoConfig ??= GenerateEncodingConfig();
config.AudioConfig ??= GenerateAudioEncodingConfig();
RenderManager.Instance.Configuration = config; RenderManager.Instance.Configuration = config;
} }
@@ -921,6 +930,7 @@ namespace ADOFAIRenderer.UI
} }
currentConfig.VideoConfig = RenderManager.Instance.Configuration.VideoConfig ?? GenerateEncodingConfig(); currentConfig.VideoConfig = RenderManager.Instance.Configuration.VideoConfig ?? GenerateEncodingConfig();
currentConfig.AudioConfig = RenderManager.Instance.Configuration.AudioConfig ?? GenerateAudioEncodingConfig();
PresetManager.SavePreset(presetName, currentConfig); PresetManager.SavePreset(presetName, currentConfig);
nameField.value = string.Empty; nameField.value = string.Empty;