Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ dotnet_style_prefer_conditional_expression_over_return = false:suggestion
dotnet_style_coalesce_expression = true:warning
dotnet_style_null_propagation = true:warning

# Use primary constructor
# https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0290
dotnet_style_prefer_primary_constructors = false
dotnet_diagnostic.IDE0290.severity = silent

# C# Code Style Settings
[*.{cs,csx,cake}]

Expand Down
15 changes: 8 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,23 @@ jobs:
fail-fast: false
matrix:
platform:
- { name: Linux, os: ubuntu-22.04 }
- { name: Windows, os: windows-2022 }
- { name: macOS x64, os: macos-13 }
- { name: macOS ARM64, os: macos-14 }
- { name: Linux x64, os: ubuntu-24.04 }
- { name: Linux arm64, os: ubuntu-24.04-arm }
- { name: Windows x64, os: windows-2025 }
- { name: Windows arm64, os: windows-11-arm }
- { name: macOS, os: macos-15 }
dotnet:
- { name: .NET 8, version: "8.0.x" }
- { name: .NET 9, version: "9.0.x" }
- { name: .NET 10, version: "10.0.x" }

steps:
- name: Check out SFML.Net
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Setup .NET ${{ matrix.dotnet.version }} SDK
id: setup-dotnet
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ matrix.dotnet.version }}
- name: Enforce SDK Version
Expand All @@ -58,7 +59,7 @@ jobs:
run: dotnet build --configuration Release --no-restore examples/Examples.sln

- name: Upload Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: SFML.Net (${{ matrix.platform.name }} ${{ matrix.dotnet.name }})
path: Publish/SFML.*.*.nupkg
4 changes: 3 additions & 1 deletion SFML.Module.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
<Import Project="SFML.CodeStyle.props" />

<PropertyGroup>
<LangVersion>12</LangVersion>

<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

Expand All @@ -18,7 +20,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CSFML" Version="[3.0.0-rc.3, 3.1)" />
<PackageReference Include="CSFML" Version="[3.0.0, 3.1)" />
</ItemGroup>

</Project>
4 changes: 2 additions & 2 deletions SFML.NuGet.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<PropertyGroup>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>

<Version>3.0.0-rc.1</Version>
<Version>3.0.0</Version>
<Authors>Laurent Gomila</Authors>
<PackageTags>sfml sfml.net</PackageTags>
<Copyright>Copyright © Laurent Gomila</Copyright>
Expand All @@ -20,7 +20,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.102" PrivateAssets="all" />

<None Include="../../sfml-icon.png" Pack="true" PackagePath=""/>
<None Include="readme.md" Pack="true" PackagePath="."/>
Expand Down
6 changes: 1 addition & 5 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ The network module is not provided in the SFML.Net binding as .NET provides supe

## State of Development

Development is focused on the next major version in the `master` branch. No more features are planned for the 2.x release series.

* The [`master`](https://github.com/SFML/SFML.Net/tree/master) branch contains work in progress for the next major version SFML.Net 3. As such it's considered unstable, but any testing and feedback is highly appreciated.
* The [`2.6.0`](https://github.com/SFML/SFML.Net/tree/2.6.0) tag is the latest official SFML.Net release and will be the last minor release in the 2.x series.
* The [`2.6.x`](https://github.com/SFML/SFML.Net/tree/2.6.x) contains the latest bugfix work on SFML.Net 2.6.x, matching CSFML's and SFML's `2.6.x` branches.
Development is focused on version 3 in the `master` branch. No more features are planned for the 2.x release series.

## Authors

Expand Down
101 changes: 50 additions & 51 deletions src/SFML.Audio/Cone.cs
Original file line number Diff line number Diff line change
@@ -1,64 +1,63 @@
using System.Runtime.InteropServices;
using SFML.System;

namespace SFML.Audio
namespace SFML.Audio;

////////////////////////////////////////////////////////////
/// <summary>
/// Structure defining the properties of a directional cone
/// <para/>
/// When set on the listener, sounds will play at gain 1 when
/// they are positioned within the inner angle of the cone.
/// Sounds will play at outerGain when they are positioned
/// outside the outer angle of the cone.
/// The gain declines linearly from 1 to outerGain as the
/// sound moves from the inner angle to the outer angle.
/// <para/>
/// When set on sound sources, they will play at gain 1 when the
/// listener is positioned within the inner angle of the cone.
/// Sounds will play at `outerGain` when the listener is
/// positioned outside the outer angle of the cone.
/// The gain declines linearly from 1 to outerGain as the
/// listener moves from the inner angle to the outer angle.
/// </summary>
////////////////////////////////////////////////////////////
public struct Cone
{
////////////////////////////////////////////////////////////
/// <summary>
/// Structure defining the properties of a directional cone
/// <para/>
/// When set on the listener, sounds will play at gain 1 when
/// they are positioned within the inner angle of the cone.
/// Sounds will play at outerGain when they are positioned
/// outside the outer angle of the cone.
/// The gain declines linearly from 1 to outerGain as the
/// sound moves from the inner angle to the outer angle.
/// <para/>
/// When set on sound sources, they will play at gain 1 when the
/// listener is positioned within the inner angle of the cone.
/// Sounds will play at `outerGain` when the listener is
/// positioned outside the outer angle of the cone.
/// The gain declines linearly from 1 to outerGain as the
/// listener moves from the inner angle to the outer angle.
/// </summary>
////////////////////////////////////////////////////////////
public struct Cone
{
/// <summary>Inner angle</summary>
public Angle InnerAngle;
/// <summary>Inner angle</summary>
public Angle InnerAngle;

/// <summary>Outer angle</summary>
public Angle OuterAngle;
/// <summary>Outer angle</summary>
public Angle OuterAngle;

/// <summary>Outer angle</summary>
public float OuterGain;
/// <summary>Outer angle</summary>
public float OuterGain;

[StructLayout(LayoutKind.Sequential)]
internal struct MarshalData
{
public float InnerAngleDegrees;
public float OuterAngleDegrees;
public float OuterGain;
}
[StructLayout(LayoutKind.Sequential)]
internal struct MarshalData
{
public float InnerAngleDegrees;
public float OuterAngleDegrees;
public float OuterGain;
}

internal Cone(MarshalData data)
{
InnerAngle = Angle.FromDegrees(data.InnerAngleDegrees);
OuterAngle = Angle.FromDegrees(data.OuterAngleDegrees);
OuterGain = data.OuterGain;
}
internal Cone(MarshalData data)
{
InnerAngle = Angle.FromDegrees(data.InnerAngleDegrees);
OuterAngle = Angle.FromDegrees(data.OuterAngleDegrees);
OuterGain = data.OuterGain;
}

// Return a marshalled version of the instance, that can directly be passed to the C API
internal MarshalData Marshal()
// Return a marshaled version of the instance, that can directly be passed to the C API
internal MarshalData Marshal()
{
var data = new MarshalData
{
var data = new MarshalData
{
InnerAngleDegrees = InnerAngle.Degrees,
OuterAngleDegrees = OuterAngle.Degrees,
OuterGain = OuterGain
};
InnerAngleDegrees = InnerAngle.Degrees,
OuterAngleDegrees = OuterAngle.Degrees,
OuterGain = OuterGain
};

return data;
}
return data;
}
}
171 changes: 85 additions & 86 deletions src/SFML.Audio/EffectProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,90 +2,89 @@
using System.Runtime.InteropServices;
using System;

namespace SFML.Audio
{
////////////////////////////////////////////////////////////
/// <summary>
/// Callable that is provided with sound data for processing
/// <para/>
/// When the audio engine sources sound data from sound
/// sources it will pass the data through an effects
/// processor if one is set. The sound data will already be
/// converted to the internal floating point format.
/// <para/>
/// Sound data that is processed this way is provided in
/// frames. Each frame contains 1 floating point sample per
/// channel. If e.g. the data source provides stereo data,
/// each frame will contain 2 floats.
/// <para/>
/// The effects processor function takes 4 parameters:
/// - The input data frames, channels interleaved
/// - The number of input data frames available
/// - The buffer to write output data frames to, channels interleaved
/// - The number of output data frames that the output buffer can hold
/// - The channel count
/// <para/>
/// The input and output frame counts are in/out parameters.
/// <para/>
/// When this function is called, the input count will
/// contain the number of frames available in the input
/// buffer. The output count will contain the size of the
/// output buffer i.e. the maximum number of frames that
/// can be written to the output buffer.
/// <para/>
/// Attempting to read more frames than the input frame
/// count or write more frames than the output frame count
/// will result in undefined behaviour.
/// <para/>
/// Attempting to read more frames than the input frame
/// count or write more frames than the output frame count
/// will result in undefined behaviour.
/// <para/>
/// It is important to note that the channel count of the
/// audio engine currently sourcing data from this sound
/// will always be provided in `frameChannelCount`. This can
/// be different from the channel count of the sound source
/// so make sure to size necessary processing buffers
/// according to the engine channel count and not the sound
/// source channel count.
/// <para/>
/// When done processing the frames, the input and output
/// frame counts must be updated to reflect the actual
/// number of frames that were read from the input and
/// written to the output.
/// <para/>
/// The processing function should always try to process as
/// much sound data as possible i.e. always try to fill the
/// output buffer to the maximum. In certain situations for
/// specific effects it can be possible that the input frame
/// count and output frame count aren't equal. As long as
/// the frame counts are updated accordingly this is
/// perfectly valid.
/// <para/>
/// If the audio engine determines that no audio data is
/// available from the data source, the input data frames
/// pointer is set to `nullptr` and the input frame count is
/// set to 0. In this case it is up to the function to
/// decide how to handle the situation. For specific effects
/// e.g. Echo/Delay buffered data might still be able to be
/// written to the output buffer even if there is no longer
/// any input data.
/// <para/>
/// An important thing to remember is that this function is
/// directly called by the audio engine. Because the audio
/// engine runs on an internal thread of its own, make sure
/// access to shared data is synchronized appropriately.
/// <para/>
/// Because this function is stored by the `SoundSource`
/// object it will be able to be called as long as the
/// `SoundSource` object hasn't yet been destroyed. Make sure
/// that any data this function references outlives the
/// SoundSource object otherwise use-after-free errors will
/// occur.
/// </summary>
////////////////////////////////////////////////////////////
public delegate long EffectProcessor(float[] inputFrames, float[] outputFrames, uint frameChannelCount);
namespace SFML.Audio;

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate long EffectProcessorInternal(IntPtr inputFrames, uint inputFrameCount, IntPtr outputFrames, uint outputFrameCount, uint frameChannelCount);
}
////////////////////////////////////////////////////////////
/// <summary>
/// Callable that is provided with sound data for processing
/// <para/>
/// When the audio engine sources sound data from sound
/// sources it will pass the data through an effects
/// processor if one is set. The sound data will already be
/// converted to the internal floating point format.
/// <para/>
/// Sound data that is processed this way is provided in
/// frames. Each frame contains 1 floating point sample per
/// channel. If e.g. the data source provides stereo data,
/// each frame will contain 2 floats.
/// <para/>
/// The effects processor function takes 4 parameters:
/// - The input data frames, channels interleaved
/// - The number of input data frames available
/// - The buffer to write output data frames to, channels interleaved
/// - The number of output data frames that the output buffer can hold
/// - The channel count
/// <para/>
/// The input and output frame counts are in/out parameters.
/// <para/>
/// When this function is called, the input count will
/// contain the number of frames available in the input
/// buffer. The output count will contain the size of the
/// output buffer i.e. the maximum number of frames that
/// can be written to the output buffer.
/// <para/>
/// Attempting to read more frames than the input frame
/// count or write more frames than the output frame count
/// will result in undefined behavior.
/// <para/>
/// Attempting to read more frames than the input frame
/// count or write more frames than the output frame count
/// will result in undefined behavior.
/// <para/>
/// It is important to note that the channel count of the
/// audio engine currently sourcing data from this sound
/// will always be provided in `frameChannelCount`. This can
/// be different from the channel count of the sound source
/// so make sure to size necessary processing buffers
/// according to the engine channel count and not the sound
/// source channel count.
/// <para/>
/// When done processing the frames, the input and output
/// frame counts must be updated to reflect the actual
/// number of frames that were read from the input and
/// written to the output.
/// <para/>
/// The processing function should always try to process as
/// much sound data as possible i.e. always try to fill the
/// output buffer to the maximum. In certain situations for
/// specific effects it can be possible that the input frame
/// count and output frame count aren't equal. As long as
/// the frame counts are updated accordingly this is
/// perfectly valid.
/// <para/>
/// If the audio engine determines that no audio data is
/// available from the data source, the input data frames
/// pointer is set to `nullptr` and the input frame count is
/// set to 0. In this case it is up to the function to
/// decide how to handle the situation. For specific effects
/// e.g. Echo/Delay buffered data might still be able to be
/// written to the output buffer even if there is no longer
/// any input data.
/// <para/>
/// An important thing to remember is that this function is
/// directly called by the audio engine. Because the audio
/// engine runs on an internal thread of its own, make sure
/// access to shared data is synchronized appropriately.
/// <para/>
/// Because this function is stored by the `SoundSource`
/// object it will be able to be called as long as the
/// `SoundSource` object hasn't yet been destroyed. Make sure
/// that any data this function references outlives the
/// SoundSource object otherwise use-after-free errors will
/// occur.
/// </summary>
////////////////////////////////////////////////////////////
public delegate long EffectProcessor(float[] inputFrames, float[] outputFrames, uint frameChannelCount);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate long EffectProcessorInternal(IntPtr inputFrames, uint inputFrameCount, IntPtr outputFrames, uint outputFrameCount, uint frameChannelCount);
Loading
Loading