Skip to content

Commit d6ae4ae

Browse files
authored
Alsa improvements (#5)
It works much better in Spectron now on Linux
1 parent 13d2bd3 commit d6ae4ae

2 files changed

Lines changed: 33 additions & 4 deletions

File tree

src/Beep/Platforms/Linux/AlsaInterop/Alsa.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ internal static partial class Alsa
66
{
77
private const string AlsaLibrary = "libasound";
88

9+
internal const int EAGAIN = 11;
10+
internal const int EPIPE = 32;
11+
912
[LibraryImport(AlsaLibrary)]
1013
internal static partial int snd_pcm_open(ref IntPtr pcm, [MarshalAs(UnmanagedType.LPStr)] string name, PcmStream stream, int mode);
1114

@@ -21,6 +24,9 @@ internal static partial class Alsa
2124
[LibraryImport(AlsaLibrary)]
2225
internal static partial int snd_pcm_prepare(IntPtr pcm);
2326

27+
[LibraryImport(AlsaLibrary)]
28+
internal static partial int snd_pcm_wait(IntPtr pcm, int timeout);
29+
2430
[LibraryImport(AlsaLibrary)]
2531
internal static partial int snd_pcm_close(IntPtr pcm);
2632

src/Beep/Platforms/Linux/AlsaPlayer.cs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,35 @@ private void RunWorker()
167167
break;
168168
}
169169

170-
var result = snd_pcm_writei(_pcm, _audioData, (ulong)(audioDataLength / _channelCount));
170+
var framesToWrite = audioDataLength / _channelCount;
171+
var frameOffset = 0;
171172

172-
if (result == -32)
173+
unsafe
173174
{
174-
result = snd_pcm_recover(_pcm, result, 0);
175-
ThrowIfError(result, "Unable to recover from buffer underrun");
175+
fixed (float* audioDataPtr = _audioData)
176+
{
177+
while (framesToWrite > 0)
178+
{
179+
var bufferOffset = audioDataPtr + frameOffset * _channelCount;
180+
var writtenCount = snd_pcm_writei(_pcm, new IntPtr(bufferOffset), (ulong)framesToWrite);
181+
182+
switch (writtenCount)
183+
{
184+
case -EPIPE:
185+
_ = snd_pcm_prepare(_pcm);
186+
continue;
187+
188+
case -EAGAIN:
189+
_ = snd_pcm_wait(_pcm, 10);
190+
continue;
191+
192+
default:
193+
frameOffset += writtenCount;
194+
framesToWrite -= writtenCount;
195+
break;
196+
}
197+
}
198+
}
176199
}
177200
}
178201
}

0 commit comments

Comments
 (0)