mirror of
https://github.com/unclshura/ABStemPlayer.git
synced 2026-08-07 00:43:38 +00:00
Fixed mono stems mixing
This commit is contained in:
parent
d14c07f457
commit
72b4a16378
@ -194,49 +194,33 @@
|
|||||||
Margin="0,0,6,0"/>
|
Margin="0,0,6,0"/>
|
||||||
|
|
||||||
<Button Command="{Binding SetPointACommand}"
|
<Button Command="{Binding SetPointACommand}"
|
||||||
Width="60"
|
Width="40"
|
||||||
Height="32"
|
Height="40"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="0,0,6,0">
|
Margin="0,0,6,0">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Path Fill="#0080ff"
|
<Path Fill="#0080ff"
|
||||||
Data="M 30 6 L 46 18 L 38 18 L 38 26 L 22 26 L 22 18 L 14 18 Z"/>
|
Data="M 26 8
|
||||||
<Path Stroke="#e0e0e0"
|
L 26 32
|
||||||
StrokeThickness="2"
|
L 14 32
|
||||||
Fill="Transparent"
|
L 24 20
|
||||||
Data="M 20 5 L 34 35 H 28 L 25 25 H 15 L 12 35 H 6 Z M 20 13 L 17 21 H 23 Z"/>
|
L 14 8
|
||||||
|
L 26 8" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button Command="{Binding SetPointBCommand}"
|
<Button Command="{Binding SetPointBCommand}"
|
||||||
Width="60"
|
Width="40"
|
||||||
Height="32"
|
Height="40"
|
||||||
Grid.Column="2">
|
Grid.Column="2">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Path Fill="#0080ff"
|
<Path Fill="#0080ff"
|
||||||
Data="M 30 26 L 46 14 L 38 14 L 38 6 L 22 6 L 22 14 L 14 14 Z"/>
|
Data="M 14 8
|
||||||
<Path Stroke="#e0e0e0"
|
L 14 32
|
||||||
StrokeThickness="2"
|
L 26 32
|
||||||
Fill="Transparent"
|
L 16 20
|
||||||
Data="
|
L 26 8
|
||||||
M 10 2.44 L 18.4 2.44
|
L 14 8"/>
|
||||||
A 6 6 0 0 1 24.4 8.44
|
|
||||||
A 6 6 0 0 1 18.4 14.44
|
|
||||||
L 22 14.44
|
|
||||||
A 5.4 5.4 0 0 1 27.4 19.84
|
|
||||||
A 5.4 5.4 0 0 1 22 25.24
|
|
||||||
L 10 25.24 Z
|
|
||||||
|
|
||||||
M 19 7.24 L 19 10.44
|
|
||||||
L 25 10.44
|
|
||||||
A 1.2 1.2 0 0 0 26.2 9.24
|
|
||||||
A 1.2 1.2 0 0 0 25 7.24 Z
|
|
||||||
|
|
||||||
M 19 14.44 L 19 19.04
|
|
||||||
L 25 19.04
|
|
||||||
A 1.8 1.8 0 0 0 26.8 17.24
|
|
||||||
A 1.8 1.8 0 0 0 25 14.44 Z
|
|
||||||
"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@ -50,18 +50,34 @@ public sealed class AudioMixer : IAudioMixer
|
|||||||
|
|
||||||
for (var i = 0; i < frames; i++)
|
for (var i = 0; i < frames; i++)
|
||||||
{
|
{
|
||||||
if (i * inChannels + 1 >= inSpan.Length)
|
var baseIndex = i * inChannels;
|
||||||
|
|
||||||
|
// If there are no samples for this frame, skip
|
||||||
|
if (baseIndex >= inSpan.Length)
|
||||||
{
|
{
|
||||||
outSpan[i * 2 + 0] = 0f;
|
outSpan[i * 2 + 0] = 0f;
|
||||||
outSpan[i * 2 + 1] = 0f;
|
outSpan[i * 2 + 1] = 0f;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var l = inChannels > 1 ? inSpan[i * inChannels + 0] : inSpan[i];
|
if (inChannels == 1)
|
||||||
var r = inChannels > 1 ? inSpan[i * inChannels + 1] : inSpan[i];
|
{
|
||||||
|
var inp = inSpan[baseIndex];
|
||||||
|
outSpan[i * 2 + 0] += inp * leftGain;
|
||||||
|
outSpan[i * 2 + 1] += inp * rightGain;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ensure both left and right samples exist for multi-channel input
|
||||||
|
if (baseIndex + 1 >= inSpan.Length)
|
||||||
|
continue; // or treat missing right as 0, depending on desired behavior
|
||||||
|
|
||||||
outSpan[i * 2 + 0] += l * leftGain;
|
var l = inSpan[baseIndex + 0];
|
||||||
outSpan[i * 2 + 1] += r * rightGain;
|
var r = inSpan[baseIndex + 1];
|
||||||
|
|
||||||
|
outSpan[i * 2 + 0] += l * leftGain;
|
||||||
|
outSpan[i * 2 + 1] += r * rightGain;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -343,9 +343,17 @@ public sealed class StemPlaybackEngine : IStemPlaybackEngine, IDisposable
|
|||||||
|
|
||||||
if (loopEnabled && loopEnd > loopStart && nextPosition >= loopEnd)
|
if (loopEnabled && loopEnd > loopStart && nextPosition >= loopEnd)
|
||||||
{
|
{
|
||||||
|
// Rewind decoders to the loop start and continue decoding so playback loops
|
||||||
|
foreach (var d in decodersSnapshot)
|
||||||
|
{
|
||||||
|
try { d.Seek(loopStart); } catch { }
|
||||||
|
}
|
||||||
|
|
||||||
lock (_stateLock)
|
lock (_stateLock)
|
||||||
_decodedFramePosition = loopEnd;
|
_decodedFramePosition = loopStart;
|
||||||
break;
|
|
||||||
|
// continue decoding from the loop start
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (_stateLock)
|
lock (_stateLock)
|
||||||
|
|||||||
@ -147,7 +147,7 @@ public sealed class AudioMixer_Tests
|
|||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
[TestCategory("ProductionBugSuspected")]
|
[TestCategory("ProductionBugSuspected")]
|
||||||
[Ignore("ProductionBugSuspected")]
|
//[Ignore("ProductionBugSuspected")]
|
||||||
public void Mixer_Handles_Mono_Stem()
|
public void Mixer_Handles_Mono_Stem()
|
||||||
{
|
{
|
||||||
// mono block
|
// mono block
|
||||||
|
|||||||
@ -302,7 +302,7 @@ public sealed class StemPlaybackEngine_Tests
|
|||||||
public async Task LoopRegion_SeeksBackOnBoundary()
|
public async Task LoopRegion_SeeksBackOnBoundary()
|
||||||
{
|
{
|
||||||
var pool = new AudioBufferPool();
|
var pool = new AudioBufferPool();
|
||||||
var decoderFactory = new MockDecoderFactory(pool, 1024, 5);
|
var decoderFactory = new MockDecoderFactory(pool, 44100, 5);
|
||||||
var output = new MockOutput();
|
var output = new MockOutput();
|
||||||
var mixer = new MockMixer(pool);
|
var mixer = new MockMixer(pool);
|
||||||
var stretch = new MockTimeStretch();
|
var stretch = new MockTimeStretch();
|
||||||
@ -320,7 +320,7 @@ public sealed class StemPlaybackEngine_Tests
|
|||||||
await engine.LoadSessionAsync(session, new DummyProgressReporter());
|
await engine.LoadSessionAsync(session, new DummyProgressReporter());
|
||||||
await engine.PlayAsync();
|
await engine.PlayAsync();
|
||||||
|
|
||||||
await Task.Delay(TimeSpan.FromSeconds(3));
|
await Task.Delay(TimeSpan.FromSeconds(6));
|
||||||
|
|
||||||
await engine.StopAsync();
|
await engine.StopAsync();
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user