SHA256
Normalize Comment Terminology
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0fc01a84de
commit
961f78a332
25 files changed
+70
-70
No files matched your search
@@ -8,7 +8,7 @@ namespace ADOFAIRenderer.Util.Audio;
|
||||
/// The frame rate is converted to an exact fraction Numerator / Denominator (<see cref="RationalUtil.Double2MaxPrecisionInt"/>).
|
||||
/// Frame k receives floor((k + 1) * sampleRate * Denominator / Numerator) - floor(k * sampleRate * Denominator / Numerator) samples:
|
||||
/// the remainder of each division is carried into the next frame, so the sum over any number of frames equals the exact
|
||||
/// sample count of that duration rounded down (for example 44100 Hz at 60 fps gives 735 every frame; at 144 fps three frames of 306
|
||||
/// sample count of that duration rounded down (for example 44100 Hz at 60 FPS gives 735 every frame; at 144 FPS three frames of 306
|
||||
/// are followed by one of 307, 306.25 on average).
|
||||
/// Used by the render thread only (RenderManager.WriteAudioForFrame, once per frame sent to the encoder).
|
||||
/// </summary>
|
||||
|
||||
@@ -175,7 +175,7 @@ internal sealed class AudioClipSource
|
||||
/// <summary>
|
||||
/// Most decode streams (reader + resampler) a windowed source opens. A load continues the stream positioned at the chunk start,
|
||||
/// otherwise opens another stream up to this count, otherwise restarts the least recently used stream.
|
||||
/// Each stream holds one open reader (file handle and decoder state, measured 0.3 ~ 2.7 MiB for ogg/flac/mp3 with the clip harness).
|
||||
/// Each stream holds one open reader (file handle and decoder state, measured 0.3 ~ 2.7 MiB for ogg/flac/MP3 with the clip harness).
|
||||
/// </summary>
|
||||
public const int MaxDecodeStreams = 4;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace ADOFAIRenderer.Util.Audio.Clip;
|
||||
/// - Decoder thread (<see cref="Start"/>): the only thread that decodes, resamples, loads and frees chunks.
|
||||
/// Each step loads one chunk, the one with the lowest priority value over all sources
|
||||
/// (a chunk a consumer waits for, then cursor windows by slot, then resident chunks in order).
|
||||
/// - Consumers (render thread, main thread for the spectrum): <see cref="Acquire"/> waits for the decoder thread and never loads.
|
||||
/// - Consumers (render thread, main Unity thread for the spectrum): <see cref="Acquire"/> waits for the decoder thread and never loads.
|
||||
/// - Main thread: <see cref="GetOrAdd"/> creates readers (for Unity clips this copies the clip data).
|
||||
///
|
||||
/// Memory has no limit; current and peak usage are tracked and logged by <see cref="LogMemoryUsage"/>.
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace ADOFAIRenderer.Util.Audio.Clip;
|
||||
/// <summary>
|
||||
/// Copies a Unity <see cref="AudioClip"/> into memory for clips without a file on disk
|
||||
/// (built-in hit sounds from Resources, official/DLC level audio).
|
||||
/// <see cref="AudioClip.GetData(float[], int)"/> runs on the main thread only, so the whole clip is copied once on the main thread
|
||||
/// <see cref="AudioClip.GetData(float[], int)"/> runs on the main Unity thread only, so the whole clip is copied once on the main Unity thread
|
||||
/// and the decoder thread reads the copy through a <see cref="MemoryPCMReader"/>.
|
||||
/// Streaming clips (<see cref="AudioClipLoadType.Streaming"/>) are rejected because GetData does not read them.
|
||||
/// Reference: https://docs.unity3d.com/ScriptReference/AudioClip.GetData.html
|
||||
|
||||
@@ -6,7 +6,7 @@ using ADOFAIRenderer.Util.Audio.Clip;
|
||||
namespace ADOFAIRenderer.Util.Audio.Mixer;
|
||||
|
||||
/// <summary>
|
||||
/// One playing sound of a <see cref="VoiceMixer"/> (the song, or one effect sound), created by <see cref="VoiceMixer.Play"/>.
|
||||
/// One playing sound of a <see cref="VoiceMixer"/> (the song, or one sound effect), created by <see cref="VoiceMixer.Play"/>.
|
||||
///
|
||||
/// Main thread: the Set methods queue a change that takes effect at a given time (seconds relative to the render start,
|
||||
/// the time at which the game made the change). Changes of one voice must be queued in non-decreasing time order.
|
||||
@@ -43,7 +43,7 @@ internal sealed class Voice
|
||||
Stop
|
||||
}
|
||||
|
||||
/// <summary>One timed change of a voice, queued by the main thread and applied by the render thread.</summary>
|
||||
/// <summary>One timed change of a voice, queued by the main Unity thread and applied by the render thread.</summary>
|
||||
internal readonly struct Change
|
||||
{
|
||||
public readonly ChangeKind Kind;
|
||||
|
||||
@@ -35,7 +35,7 @@ internal sealed class VoiceMixer : IDisposable
|
||||
Change
|
||||
}
|
||||
|
||||
/// <summary>Command queued by the main thread and taken by the render thread at the start of <see cref="Mix"/>.</summary>
|
||||
/// <summary>Command queued by the main Unity thread and taken by the render thread at the start of <see cref="Mix"/>.</summary>
|
||||
private readonly struct Command
|
||||
{
|
||||
public readonly CommandKind Kind;
|
||||
@@ -55,7 +55,7 @@ internal sealed class VoiceMixer : IDisposable
|
||||
private readonly AudioClipStore _store;
|
||||
private readonly CancellationToken _cancellationToken;
|
||||
|
||||
// Double-buffered command lists: the main thread appends to _commands under _commandLock; the render thread swaps the
|
||||
// Double-buffered command lists: the main Unity thread appends to _commands under _commandLock; the render thread swaps the
|
||||
// two lists under the lock and processes _takenCommands outside it, then clears it for the next swap.
|
||||
private readonly object _commandLock = new();
|
||||
private List<Command> _commands = new();
|
||||
@@ -126,7 +126,7 @@ internal sealed class VoiceMixer : IDisposable
|
||||
|
||||
/// <summary>
|
||||
/// Queues a change of <paramref name="voice"/> that takes effect at sample <see cref="ToSample"/>(<paramref name="time"/>).
|
||||
/// Called by the Voice Set methods on the main thread.
|
||||
/// Called by the Voice Set methods on the main Unity thread.
|
||||
/// </summary>
|
||||
internal void Enqueue(Voice voice, Voice.ChangeKind kind, double time, double value)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ using UnityEngine;
|
||||
namespace ADOFAIRenderer.Util.Audio;
|
||||
|
||||
/// <summary>
|
||||
/// Audio of one render: the song and effect sounds as <see cref="Voice"/>s of a <see cref="VoiceMixer"/>, clips from an
|
||||
/// Audio of one render: the song and sound effects as <see cref="Voice"/>s of a <see cref="VoiceMixer"/>, clips from an
|
||||
/// <see cref="AudioClipStore"/>, followed by the filter chain (RMS compressor → look-ahead limiter → hard clip → -1 dB gain).
|
||||
///
|
||||
/// Time: seconds relative to the render start (RenderManager.dspTimeBase); output sample n is at n / sample rate.
|
||||
@@ -21,15 +21,15 @@ namespace ADOFAIRenderer.Util.Audio;
|
||||
/// Threads:
|
||||
/// - Main thread: <see cref="InitializeBGM"/>, <see cref="CacheClip"/>, <see cref="RegisterSoundEvent"/>, <see cref="UpdateBGM"/>,
|
||||
/// source/voice mapping, and <see cref="Commit"/> after each frame (all commands with an earlier time have been queued).
|
||||
/// - Render thread: <see cref="GenerateAudioForFrame"/> waits until the main thread has committed the end of the samples it mixes,
|
||||
/// so every command takes effect at its own sample. <see cref="Complete"/> ends the waiting when the main thread stops.
|
||||
/// - Render thread: <see cref="GenerateAudioForFrame"/> waits until the main Unity thread has committed the end of the samples it mixes,
|
||||
/// so every command takes effect at its own sample. <see cref="Complete"/> ends the waiting when the main Unity thread stops.
|
||||
/// </summary>
|
||||
internal sealed class OfflineAudioMixer : IDisposable
|
||||
{
|
||||
/// <summary>Linear gain applied to every clip (song and effects), before the filter chain (0.5 ≈ -6 dB headroom).</summary>
|
||||
private const double ClipVolume = 0.5;
|
||||
|
||||
/// <summary>Additional gain of effect sounds (registered with <see cref="RegisterSoundEvent"/>).</summary>
|
||||
/// <summary>Additional gain of sound effects (registered with <see cref="RegisterSoundEvent"/>).</summary>
|
||||
private const double EffectVolume = 2.0 / 3.0;
|
||||
|
||||
/// <summary>
|
||||
@@ -62,7 +62,7 @@ internal sealed class OfflineAudioMixer : IDisposable
|
||||
// Main thread.
|
||||
|
||||
/// <summary>
|
||||
/// Mapping of game AudioSources to the state of the effect sound last started on them. Weak keys: a destroyed source
|
||||
/// Mapping of game AudioSources to the state of the sound effect last started on them. Weak keys: a destroyed source
|
||||
/// does not keep its state alive. Replaced by a new table to drop every mapping at once.
|
||||
/// </summary>
|
||||
private ConditionalWeakTable<AudioSource, SourceState> _sourceStates = new();
|
||||
@@ -240,7 +240,7 @@ internal sealed class OfflineAudioMixer : IDisposable
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts an effect sound at <paramref name="startTime"/>. An <paramref name="endTime"/> of 0 or more makes it loop until then.
|
||||
/// Starts a sound effect at <paramref name="startTime"/>. An <paramref name="endTime"/> of 0 or more makes it loop until then.
|
||||
/// <paramref name="source"/> (when given) is mapped to the returned state, which reports and applies later changes through the AudioSource.
|
||||
/// </summary>
|
||||
/// <param name="source">Game AudioSource playing the sound, or null to map it later with <see cref="MapSource"/>.</param>
|
||||
@@ -283,7 +283,7 @@ internal sealed class OfflineAudioMixer : IDisposable
|
||||
_sourceStates.Add(source, state);
|
||||
}
|
||||
|
||||
/// <summary>State of the effect sound last started for <paramref name="source"/>. The mapping stays after the sound ends or stops.</summary>
|
||||
/// <summary>State of the sound effect last started for <paramref name="source"/>. The mapping stays after the sound ends or stops.</summary>
|
||||
public bool TryGetSourceState(AudioSource? source, out SourceState state)
|
||||
{
|
||||
state = null!;
|
||||
@@ -291,7 +291,7 @@ internal sealed class OfflineAudioMixer : IDisposable
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops every effect sound at <paramref name="now"/>, including ones scheduled to start later
|
||||
/// Stops every sound effect at <paramref name="now"/>, including ones scheduled to start later
|
||||
/// (AudioManager.StopAllSounds destroys every AudioSource in liveSources, which holds the sources of
|
||||
/// AudioManager._Play and scrConductor.PlayWithEndTime). The song voice keeps playing.
|
||||
/// </summary>
|
||||
@@ -342,7 +342,7 @@ internal sealed class OfflineAudioMixer : IDisposable
|
||||
|
||||
/// <summary>
|
||||
/// Writes the next <paramref name="samplesNeeded"/> output frames (interleaved float, continuing from the previous call).
|
||||
/// Blocks until the main thread has committed the voice samples it needs (<see cref="Commit"/>, <see cref="Complete"/>).
|
||||
/// Blocks until the main Unity thread has committed the voice samples it needs (<see cref="Commit"/>, <see cref="Complete"/>).
|
||||
/// </summary>
|
||||
/// <param name="mixedBuffer">Destination; must hold at least samplesNeeded * channels floats. Values beyond that are untouched.</param>
|
||||
/// <param name="samplesNeeded">Frames (samples per channel) to write.</param>
|
||||
@@ -377,7 +377,7 @@ internal sealed class OfflineAudioMixer : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Mixes voices at samples [first, first + frames) into the reused double buffer, after the main thread committed them.</summary>
|
||||
/// <summary>Mixes voices at samples [first, first + frames) into the reused double buffer, after the main Unity thread committed them.</summary>
|
||||
private Span<double> MixBlock(long first, int frames)
|
||||
{
|
||||
WaitForCommit(first + frames);
|
||||
|
||||
Reference in new issue
Block a user