Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
129 commits
Select commit Hold shift + click to select a range
db5c262
bump versions
Axwabo Nov 22, 2025
16fe6da
obsolete ConditionalOneTimeDisposable
Axwabo Nov 22, 2025
ae41788
move PackageVersion
Axwabo Nov 22, 2025
34abf68
begin IAudioProcessor system
Axwabo Nov 22, 2025
3a69fe1
ProcessorChain
Axwabo Nov 22, 2025
3a22dd3
obsolete some methods + rename some stuff + dispose in Pop
Axwabo Nov 22, 2025
f169bb2
more ProcessorChainExtensions + fix docs
Axwabo Nov 22, 2025
ee3c333
use null propagation
Axwabo Nov 22, 2025
b959caf
use file + CreateAudioProcessor + stream properties
Axwabo Nov 22, 2025
901ff22
more extensions
Axwabo Nov 22, 2025
9d3847b
ISeekable + ILoopable
Axwabo Nov 22, 2025
9c3aecb
implement ILoopable & ISeekable in raw providers
Axwabo Nov 22, 2025
567ebdf
improve docs + automatically set OwnsProcessor
Axwabo Nov 22, 2025
18b2865
volume + small fixes
Axwabo Nov 22, 2025
b2c3573
rename Root + fixes + Queue to processor + short clip extensions
Axwabo Nov 22, 2025
fd45231
fix double dispose
Axwabo Nov 22, 2025
7e95cc5
properly dispose in SampleProviderQueue
Axwabo Nov 22, 2025
9071f80
reformat
Axwabo Nov 24, 2025
514d526
simplify release workflow
Axwabo Nov 24, 2025
f3213d0
Extensions.Processors namespace + more mixer methods
Axwabo Nov 24, 2025
fecf37d
move some obsolete stuff
Axwabo Nov 24, 2025
fdfced2
unprocessor things in Providers
Axwabo Nov 25, 2025
62d6ef1
StreamAudioProcessor isOwned
Axwabo Nov 25, 2025
7851a5d
move some extensions + mixer add file + WaveFormat.Time extension + S…
Axwabo Nov 25, 2025
1978ae0
remove Private="false"
Axwabo Nov 25, 2025
7351563
extension block everywhere + fix Mixer
Axwabo Nov 25, 2025
812ff12
don't unwrap MixingSampleProvider + unparent when returning to pool +…
Axwabo Nov 26, 2025
9119200
order AudioPlayer members
Axwabo Nov 26, 2025
7b6743a
TryCreateAudioProcessor + fix AudioQueue
Axwabo Nov 26, 2025
174af8e
fix docs + more global usings
Axwabo Nov 26, 2025
73ffa3d
refactor demo + more extensions
Axwabo Nov 26, 2025
5e08e5b
cleanup
Axwabo Nov 26, 2025
9251b23
group genreic extension blocks in ProcessorChainExtensions
Axwabo Nov 26, 2025
fefc8c5
remove ConvertAndRetrieve
Axwabo Nov 26, 2025
b19232a
fix mixer
Axwabo Nov 26, 2025
9031f13
rename DiscJockeyProcessor + move DJ board check priority
Axwabo Nov 26, 2025
eb2b1ba
fix IsDestroyed check
Axwabo Nov 26, 2025
d2dee3b
re-add DiscJockeySampleProvider + demo readme
Axwabo Nov 26, 2025
7ee9e8a
maxDuration in ShortClipCache + improve provider ownership
Axwabo Nov 27, 2025
7d762fa
move some methods
Axwabo Nov 27, 2025
e1b464a
mix short clips + process delegate
Axwabo Nov 27, 2025
b7065d4
begin ProcessDelegate
Axwabo Nov 27, 2025
a4718a2
rename & move Process delegate
Axwabo Nov 27, 2025
088eb4e
optimize UseMixer + volume support in use methods
Axwabo Dec 1, 2025
40b7b28
begin docs
Axwabo Dec 2, 2025
8453788
more docs
Axwabo Dec 5, 2025
afa27ba
even more docs
Axwabo Dec 9, 2025
516b8d5
obsolete LoopingRawSampleProvider
Axwabo Dec 9, 2025
164ff18
slightly optimize RawSourceSampleProvider read
Axwabo Dec 9, 2025
5fd3580
Revert "slightly optimize RawSourceSampleProvider read"
Axwabo Dec 9, 2025
a1ff6f5
fix RSSP read length check
Axwabo Dec 9, 2025
175f222
fix Swap + more docs
Axwabo Dec 16, 2025
be27470
docs progress
Axwabo Dec 18, 2025
1148b61
remove float extensions
Axwabo Dec 18, 2025
2874ce1
rename ProcessorInputExtensions + docs
Axwabo Dec 20, 2025
e750398
docs progress numero idk
Axwabo Dec 21, 2025
8919a6c
remove IncludeBuildOutput override
Axwabo Dec 24, 2025
457b9bd
use searchOption in ShortClipCache
Axwabo Dec 26, 2025
b3e77dd
docs progress + owned WaveProviderToProcessor
Axwabo Dec 26, 2025
5623fb4
complete ProviderToProcessor docs + SampleProviderToProcessor ownership
Axwabo Dec 27, 2025
dbcbf5b
docs progress + more ShortClipCache methods
Axwabo Jan 2, 2026
0143c0b
complete obsolete messages + player mixer remove extensions
Axwabo Jan 2, 2026
e455a5f
personalization ClearAll + SendSyncVars safeguard
Axwabo Jan 2, 2026
05799f5
fix XmlDocs formatting
Axwabo Jan 2, 2026
b430184
more docs number idk
Axwabo Jan 2, 2026
0237d1e
GloballyAudible SpeakerSettings + remove stage position setter in demo
Axwabo Jan 2, 2026
b5c1786
remove AddProcess paramref
Axwabo Jan 2, 2026
753281a
optimize ProcessorChain.Layers
Axwabo Jan 2, 2026
8fc1e08
include System.ValueTuple in builds
Axwabo Jan 2, 2026
ac74612
final turn before finish line (docs)
Axwabo Jan 3, 2026
a7d2529
finish docs
Axwabo Jan 3, 2026
cd80f20
UseFileSafe
Axwabo Jan 3, 2026
62a7fe7
Enumerable.Repeat
Axwabo Jan 3, 2026
b16c2e1
don't set OwnsProvider to true in OnDisable
Axwabo Jan 3, 2026
77cf17a
implement ISeekable in LoopingWaveProvider
Axwabo Jan 3, 2026
52ce590
Props in Directory.Build.targets
Axwabo Jan 3, 2026
51f9161
rename Inputs.cs
Axwabo Jan 3, 2026
4b59b32
LogError in AudioPlayer::SampleProvider
Axwabo Jan 4, 2026
0166857
WitLivePersonalizedSendEngine overload without personalization component
Axwabo Jan 4, 2026
f6dabb0
rename Play & Stop
Axwabo Jan 4, 2026
f0b7100
groups attempt
Axwabo Jan 11, 2026
5a41ee9
bump version
Axwabo Jan 11, 2026
a1e43d5
begin path-based inheritdoc pruning
Axwabo Jan 29, 2026
7b9d36a
pools docs fix progress
Axwabo Jan 29, 2026
627df5a
groups attempt #2
Axwabo Jan 29, 2026
99de570
begin player queue extensions
Axwabo Jan 29, 2026
93d1682
Queue.xml progress
Axwabo Jan 29, 2026
9a451a6
more docs cleanup
Axwabo Feb 3, 2026
8dbbad9
almost comlete inheritdoc path pruning
Axwabo Feb 3, 2026
d0f3144
complete pruning pathful inheritdoc
Axwabo Feb 3, 2026
27e84f5
begin ClipName struct
Axwabo Feb 4, 2026
0a612e4
use ClipName in most places
Axwabo Feb 4, 2026
fbae0ca
remove string overloads for ShortClipCache.Get(Safe)
Axwabo Feb 4, 2026
7bbd72a
more ClipName overloads
Axwabo Feb 5, 2026
7d88949
ClipName in all AP Mixer extensions
Axwabo Feb 5, 2026
cea15c9
dispose before throwing invalid format if owned
Axwabo Feb 5, 2026
63655c6
implement SpeakerToyGroup
Axwabo Feb 5, 2026
341dce1
don't return to the pool if destroying was requested
Axwabo Feb 5, 2026
3570ee5
delegate to SpeakerToy group props/methods + grouping docs
Axwabo Feb 5, 2026
71d1bfb
group extensions
Axwabo Feb 5, 2026
bb27d16
ClipName in enqueue
Axwabo Feb 5, 2026
0a41251
short clip ModifyChain overloads
Axwabo Feb 6, 2026
d6c7227
complete Enqueue docs
Axwabo Feb 6, 2026
efa809f
move Speaker and Id up
Axwabo Feb 6, 2026
2086cff
remove loop from queue methods
Axwabo Feb 6, 2026
5583f4f
remove final pathful inheritdoc
Axwabo Feb 6, 2026
65f2f9a
throw if accessing the controller of a destroyed group
Axwabo Feb 6, 2026
c902cb0
SpeakerToyGroup extension props
Axwabo Feb 6, 2026
eea4e7f
IsPooled methods + improve grou extension props
Axwabo Feb 6, 2026
950c4f2
note Destroy in exception
Axwabo Feb 6, 2026
d3267e0
reword SpeakersPerGroup docs
Axwabo Feb 7, 2026
4dddfe4
bump LabAPI
Axwabo Feb 7, 2026
3585df0
null check in IsPooled
Axwabo Feb 7, 2026
fe0f6e1
fix group removal
Axwabo Feb 7, 2026
a1d6398
unity lifetime check in APPool.Return
Axwabo Feb 7, 2026
da1e28c
actually fix group destroying + improve lifetime checks
Axwabo Feb 7, 2026
99b62f5
force create speaker CTS
Axwabo Feb 7, 2026
daa1226
update README.md
Axwabo Feb 7, 2026
c7dfd8a
fix UseMixer with keepInputs
Axwabo Feb 7, 2026
b6a6df7
fix word repeat
Axwabo Feb 7, 2026
94aeef8
bump version
Axwabo Feb 7, 2026
ad55dca
StreamAudioProcessor.FileName
Axwabo Feb 8, 2026
0a74df2
fix CreateAudioProcessor.FromStream docs
Axwabo Feb 8, 2026
bb3b174
fix ClipName docs
Axwabo Feb 8, 2026
d143c88
bump version
Axwabo Feb 8, 2026
76cf603
update README
Axwabo Feb 8, 2026
897e36d
Ended event
Axwabo Feb 21, 2026
e1cfe3a
bump version
Axwabo Feb 21, 2026
542100e
fix xml doc
Axwabo Feb 21, 2026
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
45 changes: 8 additions & 37 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Release

on:
release:
types: [ created ]
types: [ published ]

permissions:
contents: write
Expand All @@ -11,53 +11,24 @@ jobs:

release:
runs-on: ubuntu-latest

env:
ReferenceUrl: https://exmod-team.github.io/SL-References/Dev.zip
ReferencePath: ${{ github.workspace }}/References

steps:

- uses: actions/checkout@v4

- name: Set Up .NET
uses: actions/setup-dotnet@v4.0.1
with:
dotnet-version: 9.0.x

- name: Download References
run: |
wget -O "References.zip" ${{ env.ReferenceUrl }}
unzip -d ${{ env.ReferencePath }} "References.zip"
- uses: actions/checkout@v6

- name: Rename Assembly-CSharp
working-directory: ${{ env.ReferencePath }}
run: mv Assembly-CSharp-Publicized.dll Assembly-CSharp.dll
- uses: Axwabo/scpsl-references-downloader@v1

- name: Build
run: dotnet build -c:Release -o Output
run: dotnet build -c Release -o Out

- name: Create Bundle
working-directory: Output
run: |
mkdir SecretLabNAudio
mkdir SecretLabNAudio/bin
mkdir SecretLabNAudio/LICENSES

mv SecretLabNAudio.dll SecretLabNAudio/bin
ls | grep -E "^(NAudio|NLayer|NVorbis)" | xargs -I {0} mv {0} SecretLabNAudio/bin

cp -r ../THIRD_PARTY_LICENSES SecretLabNAudio/LICENSES
cp ../LICENSE SecretLabNAudio/LICENSES/SecretLabNAudio.txt

cd SecretLabNAudio
zip -r ../SecretLabNAudio.zip .
working-directory: Out
run: ${{ github.workspace }}/bundle.sh

- name: Upload Assets
uses: softprops/action-gh-release@v2
with:
files: Output/SecretLabNAudio*.dll,Output/SecretLabNAudio*.xml,Output/SecretLabNAudio.zip
files: Out/SecretLabNAudio*.dll,Out/SecretLabNAudio*.xml,Out/SecretLabNAudio.zip

- name: Push to NuGet
working-directory: Output
working-directory: Out
run: dotnet nuget push SecretLabNAudio.*.nupkg -k ${{ secrets.NUGET_API_KEY }} -s https://api.nuget.org/v3/index.json
23 changes: 13 additions & 10 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>13</LangVersion>
<LangVersion>14</LangVersion>
<PlatformTarget>x64</PlatformTarget>
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
<Version>1.0.2</Version>
<Version>2.0.0</Version>
<PackageVersion>2.0.0-alpha5</PackageVersion>
</PropertyGroup>

<ItemGroup>
Expand All @@ -14,24 +15,26 @@
</ItemGroup>

<ItemGroup>
<Reference Include="mscorlib" Private="false" />
<Reference Include="System" Private="false" />
<Reference Include="System.Core" Private="false" />
<Reference Include="System.Data" Private="false" />
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
</ItemGroup>

<ItemGroup>
<Reference Include="Assembly-CSharp" Private="false" />
<Reference Include="Mirror" Private="false" />
<Reference Include="UnityEngine.CoreModule" Private="false" />
<Reference Include="Assembly-CSharp" />
<Reference Include="Mirror" />
<Reference Include="UnityEngine.CoreModule" />
</ItemGroup>

<ItemGroup>
<Using Include="System" />
<Using Include="System.Collections.Generic" />
<Using Include="System.Diagnostics.CodeAnalysis" />
<Using Include="System.IO" />
<Using Include="LabApi.Features.Wrappers" />
<Using Include="Mirror" />
<Using Include="NAudio.Wave" />
<Using Include="SecretLabNAudio.Core.Extensions" />
<Using Include="UnityEngine" />
<Using Include="UnityEngine.Object" Alias="Object" />
</ItemGroup>
Expand Down
21 changes: 11 additions & 10 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
<Project>
<Import Project="ReferencePath.props.user" Condition="Exists('ReferencePath.props.user')"/>
<Import Project="ReferencePath.props.user" Condition="Exists('ReferencePath.props.user')" />
<PropertyGroup>
<ReferencePath Condition="$(ReferencePath) == ''">$(SL_REFERENCES)</ReferencePath>
<AssemblySearchPaths>$(ReferencePath);$(AssemblySearchPaths)</AssemblySearchPaths>
</PropertyGroup>

<Target Name="NotifyIncompleteSetup" BeforeTargets="PrepareForBuild" Condition="$(ReferencePath) == ''">
<PropertyGroup>
<Template>
&lt;Project&gt;
&lt;PropertyGroup&gt;
&lt;ReferencePath&gt;&lt;/ReferencePath&gt;
&lt;/PropertyGroup&gt;
&lt;/Project&gt;
</Template>
<Props>$(MSBuildThisFileDirectory)ReferencePath.props.user</Props>
<Template><![CDATA[
<Project>
<PropertyGroup>
<ReferencePath></ReferencePath>
</PropertyGroup>
</Project>
]]></Template>
</PropertyGroup>
<WriteLinesToFile File="$(MSBuildThisFileDirectory)ReferencePath.props.user" Lines="$(Template)" Condition="!Exists('$(MSBuildThisFileDirectory)ReferencePath.props.user')" />
<WriteLinesToFile File="$(Props)" Lines="$(Template)" Condition="!Exists($(Props))" />
<Error Text="The ReferencePath property is not specified! Make sure to set the property in the ReferencePath.props.user file." />
</Target>
</Project>
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<ItemGroup>
<PackageVersion Include="NAudio.Core" Version="2.2.1" />
<PackageVersion Include="Northwood.LabAPI" Version="1.1.3" />
<PackageVersion Include="Northwood.LabAPI" Version="1.1.5" />

<PackageVersion Include="NAudio.Wasapi" Version="2.2.1" />

Expand Down
49 changes: 30 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ This library has a number of open-source dependencies. See [Attributions](ATTRIB
> [!NOTE]
> SecretLabNAudio is not sponsored nor endorsed by NAudio.

> [!IMPORTANT]
> If you're still using v1, [migrate to v2](https://github.com/Axwabo/SecretLabNAudio/wiki/Migration-Guide)

# Features

[Watch the demo](https://youtu.be/6btaXm3BU8s)
Expand All @@ -25,15 +28,16 @@ This library has a number of open-source dependencies. See [Attributions](ATTRIB

> [!TIP]
> Check the [wiki](https://github.com/Axwabo/SecretLabNAudio/wiki) for more information.
> See [this page](https://github.com/Axwabo/SecretLabNAudio/wiki/Examples) for examples.

# Installation

## Single-File

1. Download the `SecretLabNAudio.zip` file from the [releases page](https://github.com/Axwabo/SecretLabNAudio/releases)
2. Extract `bin/SecretLabNAudio.dll` from the archive into the **global plugins** directory
- Linux: `.config/SCP Secret Laboratory/LabAPI/plugins/global/`
- Windows: `%appdata%/SCP Secret Laboratory/LabAPI/plugins/global/`
- Linux: `~/.config/SCP Secret Laboratory/LabAPI/plugins/global/`
- Windows: `%appdata%/SCP Secret Laboratory/LabAPI/plugins/global/`
3. Restart the server

> [!IMPORTANT]
Expand All @@ -43,23 +47,30 @@ This library has a number of open-source dependencies. See [Attributions](ATTRIB
## Modular

1. Download the `SecretLabNAudio.Core.dll` file from the [releases page](https://github.com/Axwabo/SecretLabNAudio/releases)
2. Place the file in the **dependencies** directory
- Linux: `.config/SCP Secret Laboratory/LabAPI/dependencies/<port>/`
- Windows: `%appdata%/SCP Secret Laboratory/LabAPI/dependencies/<port>/`
3. Download the `SecretLabNAudio.zip` file from the releases page
4. Extract the necessary files from the `bin/` directory of the archive as **dependencies**
- `NAudio.Core.dll` is **always required**
- `NLayer` and `NLayer.NAudioSpport.dll` for `.mp3` support (optional)
- `NAudio.Vorbis.dll` and `NVorbis.dll` for `.ogg` support (optional)
- `NAudio.Wasapi.dll` for Media Foundation support (optional, WIndows-only)
5. Optionally download the necessary **plugin(s)** from the releases page
- `SecretLabNAudio.NLayer.dll` for `.mp3` support
- `SecretLabNAudio.NVorbis.dll` for `.ogg` support
- `SecretLabNAudio.MediaFoundation.dll` for Media Foundation support (Windows-only)
6. Place the downloaded plugin(s) into the **plugins** directory
- Linux: `.config/SCP Secret Laboratory/LabAPI/plugins/<port>/`
- Windows: `%appdata%/SCP Secret Laboratory/LabAPI/plugins/<port>/`
7. Restart the server
2. Download the `SecretLabNAudio.zip` file from the releases page
3. Extract the necessary DLLs from the `bin/` directory
- See the [table below](#modules) for what you need
- Place dependencies into the **dependencies** directory
- Linux: `~/.config/SCP Secret Laboratory/LabAPI/dependencies/<port>/`
- Windows: `%appdata%/SCP Secret Laboratory/LabAPI/dependencies/<port>/`
- Place plugins into the **plugins** directory
- Linux: `~/.config/SCP Secret Laboratory/LabAPI/plugins/<port>/`
- Windows: `%appdata%/SCP Secret Laboratory/LabAPI/plugins/<port>/`
4. Restart the server

### Modules

To support reading from some file formats, install the modules you need.

| Usage | Plugin | Dependencies |
|--------------|------------------------------------|-----------------------------------------------|
| **required** | (none) | `SecretLabNAudio.Core` `NAudio.Core` |
| mp3 | `SecretLabNAudio.NLayer` | `NLayer` `NLayer.NAudioSupport` |
| ogg | `SecretLabNAudio.NVorbis` | `NVorbis` `NAudio.Vorbis` `System.ValueTuple` |
| most formats | `SecretLabNAudio.MediaFoundation`* | `NAudio.Wasapi`* |

> [!NOTE]
> *MediaFoundation is only available on Windows.

## Development

Expand Down
4 changes: 3 additions & 1 deletion SecretLabNAudio.Core/AudioPlayer.Create.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace SecretLabNAudio.Core;
using SecretLabNAudio.Core.Extensions;

namespace SecretLabNAudio.Core;

public partial class AudioPlayer
{
Expand Down
9 changes: 1 addition & 8 deletions SecretLabNAudio.Core/AudioPlayer.Format.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,7 @@ public partial class AudioPlayer

/// <summary>Checks if the given provider is not compatible with <see cref="AudioPlayer"/>s.</summary>
/// <param name="provider">The provider to check. Null values are skipped.</param>
/// <exception cref="ArgumentException">
/// Thrown when the given sample provider is not null and does not match the following criteria:
/// <para>
/// Encoding = <see cref="WaveFormatEncoding.IeeeFloat"/><br/>
/// Sample Rate = <see cref="SampleRate"/><br/>
/// Channels = <see cref="Channels"/>
/// </para>
/// </exception>
/// <include file='XmlDocs/Providers.xml' path='doc/Format/exception'/>
public static void ThrowIfIncompatible(ISampleProvider? provider)
{
if (provider is {WaveFormat: not {SampleRate: SampleRate, Channels: Channels, Encoding: WaveFormatEncoding.IeeeFloat}})
Expand Down
Loading