SCPSL-AudioManagerAPI
1.0.0
See the version list below for details.
dotnet add package SCPSL-AudioManagerAPI --version 1.0.0
NuGet\Install-Package SCPSL-AudioManagerAPI -Version 1.0.0
<PackageReference Include="SCPSL-AudioManagerAPI" Version="1.0.0" />
<PackageVersion Include="SCPSL-AudioManagerAPI" Version="1.0.0" />
<PackageReference Include="SCPSL-AudioManagerAPI" />
paket add SCPSL-AudioManagerAPI --version 1.0.0
#r "nuget: SCPSL-AudioManagerAPI, 1.0.0"
#:package SCPSL-AudioManagerAPI@1.0.0
#addin nuget:?package=SCPSL-AudioManagerAPI&version=1.0.0
#tool nuget:?package=SCPSL-AudioManagerAPI&version=1.0.0
SCPSL-AudioManagerAPI
A lightweight, reusable C# library for managing audio playback in SCP: Secret Laboratory (SCP:SL) plugins using LabAPI. It provides a robust system for loading, caching, and playing audio through SpeakerToy
instances, with centralized controller ID management to prevent conflicts across multiple plugins.
Features
- Centralized Controller ID Management: Uses
ControllerIdManager
to ensure unique speaker IDs (1-255) across all plugins, preventing conflicts in multiplayer environments. - LRU Audio Caching: Efficiently manages audio samples with lazy loading and least-recently-used (LRU) eviction via
AudioCache
. - Flexible Speaker Abstraction: Supports custom speaker implementations through
ISpeaker
andISpeakerFactory
interfaces. - Thread-Safe Operations: Handles concurrent audio playback, caching, and ID allocation safely.
- LabAPI Compatibility: Optimized for SCP:SL, integrating seamlessly with
SpeakerToy
for spatial audio playback.
Installation
Install the SCPSL-AudioManagerAPI
package via NuGet:
dotnet add package SCPSL-AudioManagerAPI --version 1.0.0
Or, in Visual Studio, use the NuGet Package Manager to search for SCPSL-AudioManagerAPI
.
Project Setup
Add the SCPSL-AudioManagerAPI
package to your SCP:SL plugin project. Ensure you reference UnityEngine.CoreModule
for Vector3
and LabApi
for SpeakerToy
integration.
Example .csproj
snippet:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SCPSL-AudioManagerAPI" Version="1.0.0" />
<Reference Include="LabApi">
<HintPath>path\to\LabApi.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>path\to\UnityEngine.CoreModule.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
Usage
1. Implement ISpeaker and ISpeakerFactory
Create a custom speaker implementation compatible with LabAPI's SpeakerToy
.
using AudioManagerAPI.Features.Speakers;
using LabApi.Features.Wrappers;
using UnityEngine;
public class LabApiSpeaker : ISpeaker
{
private readonly SpeakerToy speakerToy;
public LabApiSpeaker(SpeakerToy speakerToy)
{
this.speakerToy = speakerToy ?? throw new ArgumentNullException(nameof(speakerToy));
}
public void Play(float[] samples, bool loop)
{
var transmitter = SpeakerToy.GetTransmitter(speakerToy.ControllerId);
transmitter?.Play(samples, queue: false, loop: loop);
}
public void Stop()
{
var transmitter = SpeakerToy.GetTransmitter(speakerToy.ControllerId);
transmitter?.Stop();
}
public void Destroy()
{
speakerToy.Destroy();
}
// Optional: Configure which players can hear the audio
public void SetValidPlayers(Func<Player, bool> playerFilter)
{
var transmitter = SpeakerToy.GetTransmitter(speakerToy.ControllerId);
if (transmitter != null)
{
transmitter.ValidPlayers = playerFilter;
}
}
}
public class LabApiSpeakerFactory : ISpeakerFactory
{
public ISpeaker CreateSpeaker(Vector3 position, byte controllerId)
{
SpeakerToy speaker = SpeakerToy.Create(position, networkSpawn: true);
if (speaker == null) return null;
speaker.ControllerId = controllerId;
return new LabApiSpeaker(speaker);
}
}
2. Initialize AudioManager
Create an instance of AudioManager
with your ISpeakerFactory
and register audio resources. The AudioCache
supports only 48kHz, Mono, Signed 16-bit PCM WAV files.
using AudioManagerAPI.Features.Management;
using System;
using System.Reflection;
public class MyPluginAudioManager
{
private readonly IAudioManager audioManager;
public MyPluginAudioManager()
{
audioManager = new AudioManager(new LabApiSpeakerFactory(), cacheSize: 20);
RegisterAudioResources();
}
private void RegisterAudioResources()
{
var assembly = Assembly.GetExecutingAssembly();
audioManager.RegisterAudio("myplugin.scream", () =>
assembly.GetManifestResourceStream("MyPlugin.Audio.scream.wav"));
}
}
3. Play Audio
Use IAudioManager
to play audio at specific positions, with optional speaker configuration.
using UnityEngine;
public void PlayScream(Vector3 position, Player targetPlayer)
{
byte? controllerId = audioManager.PlayAudio("myplugin.scream", position, false, speaker =>
{
if (speaker is LabApiSpeaker labSpeaker)
{
labSpeaker.SetValidPlayers(p => p == targetPlayer);
}
});
if (controllerId.HasValue)
{
Log.Info($"Played scream with controller ID {controllerId.Value}.");
}
}
4. Manage Speakers
Stop Audio: Stop playback for a specific speaker.
audioManager.StopAudio(controllerId);
Destroy Speaker: Free resources for a specific speaker.
audioManager.DestroySpeaker(controllerId);
Retrieve Speaker: Access a speaker for further configuration.
ISpeaker speaker = audioManager.GetSpeaker(controllerId);
5. Cleanup
Clean up all speakers to free resources.
audioManager.CleanupAllSpeakers();
Audio Requirements
The AudioCache
class processes WAV files with the following specifications:
- Format: 48kHz, Mono, Signed 16-bit PCM.
- Header: Expects a standard WAV header; skips the first 44 bytes during loading.
- Recommendation: Prefix audio keys with your plugin’s namespace (e.g.,
myplugin.scream
) to avoid conflicts with other plugins.
API Reference
Key Classes and Interfaces
Name | Namespace | Description |
---|---|---|
IAudioManager |
AudioManagerAPI.Features.Management |
Defines the contract for audio playback and speaker lifecycle management. |
AudioManager |
AudioManagerAPI.Features.Management |
Implements audio management with caching and shared controller IDs. |
ISpeaker |
AudioManagerAPI.Features.Speakers |
Represents a speaker for playing audio samples at a position. |
ISpeakerFactory |
AudioManagerAPI.Features.Speakers |
Defines a factory for creating speaker instances. |
AudioCache |
AudioManagerAPI.Cache |
Manages audio samples with LRU eviction and lazy loading. |
ControllerIdManager |
AudioManagerAPI |
Static class for managing unique controller IDs across plugins. |
Important Methods
IAudioManager.RegisterAudio(string key, Func<Stream> streamProvider)
: Registers a WAV stream for lazy loading.IAudioManager.PlayAudio(string key, Vector3 position, bool loop, Action<ISpeaker> configureSpeaker)
: Plays audio at a position with optional configuration.IAudioManager.StopAudio(byte controllerId)
: Stops audio for a specific speaker.IAudioManager.DestroySpeaker(byte controllerId)
: Destroys a speaker and releases its ID.IAudioManager.CleanupAllSpeakers()
: Cleans up all active speakers and releases their IDs.IAudioManager.GetSpeaker(byte controllerId)
: Retrieves a speaker instance for further configuration.
Notes
- Controller ID Synchronization:
ControllerIdManager
ensures no ID conflicts by maintaining a shared pool of IDs (1-255), critical for SCP:SL’s multiplayer environment. - Thread Safety: All operations (ID allocation, caching, speaker management) are thread-safe using locks.
- Dependencies: Requires
UnityEngine.CoreModule
forVector3
andLabApi
forSpeakerToy
. Ensure these are available in your SCP:SL environment. - Logging: Use your plugin’s logging system (e.g., Exiled’s
Log
) for debugging playback or resource errors.
Contributing
Contributions are welcome! Please submit issues or pull requests to the GitHub repository.
License
This project is licensed under the GNU Lesser General Public License v3.0 (LGPL3). See the LICENSE file for details.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET Framework | net48 is compatible. net481 was computed. |
-
.NETFramework 4.8
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
1.7.0 | 120 | 7/28/2025 |
1.6.0 | 71 | 7/27/2025 |
1.5.2 | 215 | 7/26/2025 |
1.5.1 | 216 | 7/26/2025 |
1.5.0 | 444 | 7/24/2025 |
1.4.2 | 446 | 7/24/2025 |
1.4.1 | 439 | 7/24/2025 |
1.4.0 | 444 | 7/24/2025 |
1.3.0 | 445 | 7/23/2025 |
1.2.3 | 491 | 7/22/2025 |
1.2.2 | 490 | 7/22/2025 |
1.2.1 | 495 | 7/22/2025 |
1.2.0 | 493 | 7/22/2025 |
1.0.3 | 490 | 7/22/2025 |
1.0.2 | 460 | 7/21/2025 |
1.0.1 | 459 | 7/21/2025 |
1.0.0 | 460 | 7/21/2025 |