Skip to content

Commit

Permalink
Merge pull request #5 from SineVector241/dev
Browse files Browse the repository at this point in the history
Sync Dev to Master.
  • Loading branch information
SineVector241 authored Jun 25, 2024
2 parents bd87600 + 2097c3d commit 8cd596a
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 12 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: BuildTest
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Dotnet
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.x'

- name: Install Dependencies
run: dotnet workload restore ./OpusSharp.Core/OpusSharp.Core.csproj

- name: Build
run: dotnet build ./OpusSharp.Core/OpusSharp.Core.csproj -f netstandard2.0 -p:TargetFrameworks=netstandard2.0
16 changes: 16 additions & 0 deletions OpusSharp.Core/Disposable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,24 @@ public abstract class Disposable : IDisposable
{
private int isDisposed; // 0 for false, 1 for true

/// <summary>
/// Returns wether the object is disposed or not.
/// </summary>
public bool IsDisposed
{
get => Volatile.Read(ref this.isDisposed) != 0;
}

/// <summary>
/// Makes an object disposable.
/// </summary>
protected Disposable()
{
}

/// <summary>
/// When the object is destructed and not disposed, it does not dispose.
/// </summary>
~Disposable()
{
int oldIsDisposed = Interlocked.Exchange(ref this.isDisposed, 1);
Expand All @@ -35,6 +44,9 @@ protected Disposable()
}
}

/// <summary>
/// Disposes the object.
/// </summary>
public void Dispose()
{
int oldIsDisposed = Interlocked.Exchange(ref this.isDisposed, 1);
Expand All @@ -51,6 +63,10 @@ public void Dispose()
}
}

/// <summary>
/// Disposes the object.
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
throw new NotImplementedException();
Expand Down
9 changes: 7 additions & 2 deletions OpusSharp.Core/OpusDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,10 @@ public unsafe int Decode(byte[] input, int inputLength, short[] output, int fram
/// Decodes an Opus frame.
/// </summary>
/// <param name="input">Input in float format (interleaved if 2 channels), with a normal range of +/-1.0. Samples with a range beyond +/-1.0 are supported but will be clipped by decoders using the integer API and should only be used if it is known that the far end supports extended dynamic range. length is frame_size*channels*sizeof(float)</param>
/// <param name="frame_size">Number of samples per channel in the input signal. This must be an Opus frame size for the encoder's sampling rate. For example, at 48 kHz the permitted values are 120, 240, 480, 960, 1920, and 2880. Passing in a duration of less than 10 ms (480 samples at 48 kHz) will prevent the encoder from using the LPC or hybrid modes.</param>
/// <param name="inputLength">Number of samples per channel in the input signal. This must be an Opus frame size for the encoder's sampling rate. For example, at 48 kHz the permitted values are 120, 240, 480, 960, 1920, and 2880. Passing in a duration of less than 10 ms (480 samples at 48 kHz) will prevent the encoder from using the LPC or hybrid modes.</param>
/// <param name="output">Output payload</param>
/// <param name="frame_size">The number of samples per channel of available space in pcm. If this is less than the maximum packet duration (120 ms; 5760 for 48kHz), this function will not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), then frame_size needs to be exactly the duration of audio that is missing, otherwise the decoder will not be in the optimal state to decode the next incoming packet. For the PLC and FEC cases, frame_size must be a multiple of 2.5 ms.</param>
/// <param name="decodeFEC">Flag (false or true) to request that any in-band forward error correction data be decoded. If no such data is available, the frame is decoded as if it were lost.</param>
/// <param name="inputOffset">Offset to start reading in the input.</param>
/// <param name="outputOffset">Offset to start writing in the output.</param>
/// <returns>The length of the decoded packet on success or a negative error code (see <see cref="Enums.OpusError"/>) on failure. Note: OpusSharp throws an error if there is a negative error code.</returns>
Expand Down Expand Up @@ -210,7 +212,6 @@ public void DecoderCtl(Enums.GenericCtl ctl, int value)
/// Requests a CTL on the decoder.
/// </summary>
/// <param name="ctl">The decoder CTL to request.</param>
/// <param name="value">The value that is outputted from the CTL.</param>
/// <exception cref="ObjectDisposedException"></exception>
/// <exception cref="OpusException"></exception>
public int DecoderCtl(Enums.GenericCtl ctl)
Expand Down Expand Up @@ -238,6 +239,10 @@ public int GetNumberOfSamples(byte[] data)
return result;
}

/// <summary>
/// Disposes the object.
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
if (disposing)
Expand Down
5 changes: 4 additions & 1 deletion OpusSharp.Core/OpusEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ public void EncoderCtl(Enums.EncoderCtl ctl, int value)
/// Requests a CTL on the encoder.
/// </summary>
/// <param name="ctl">The encoder CTL to request.</param>
/// <param name="value">The value that is outputted from the CTL.</param>
/// <exception cref="ObjectDisposedException"></exception>
/// <exception cref="OpusException"></exception>
public int EncoderCtl(Enums.EncoderCtl ctl)
Expand Down Expand Up @@ -299,6 +298,10 @@ public int EncoderCtl(Enums.GenericCtl ctl)
return val;
}

/// <summary>
/// Disposes the object.
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
if (disposing)
Expand Down
15 changes: 15 additions & 0 deletions OpusSharp.Core/OpusException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,27 @@

namespace OpusSharp.Core
{
/// <summary>
/// An opus exception.
/// </summary>
public class OpusException : Exception
{
/// <summary>
/// Contructs an opus exception.
/// </summary>
public OpusException() { }

/// <summary>
/// Contructs an opus exception.
/// </summary>
/// <param name="message">The message of the exception.</param>
public OpusException(string message) : base(message) { }

/// <summary>
/// Contructs an opus exception.
/// </summary>
/// <param name="message">The message of the exception.</param>
/// <param name="innerException">The root exception.</param>
public OpusException(string message, Exception innerException) : base(message, innerException) { }
}
}
12 changes: 10 additions & 2 deletions OpusSharp.Core/OpusMSDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ public int Pitch
/// </summary>
/// <param name="SampleRate">Sample rate to decode at (Hz). This must be one of 8000, 12000, 16000, 24000, or 48000.</param>
/// <param name="Channels">Number of channels to decode.</param>
/// <param name="Streams">The total number of streams coded in the input. This must be no more than 255.</param>
/// <param name="CoupledStreams">Number of streams to decode as coupled (2 channel) streams. This must be no larger than the total number of streams. Additionally, The total number of coded channels (streams + coupled_streams) must be no more than 255.</param>
/// <param name="mapping">Mapping from coded channels to output channels, as described in Opus Multistream API.</param>
/// <exception cref="OpusException"></exception>
public unsafe OpusMSDecoder(int SampleRate, int Channels, int Streams, int CoupledStreams, byte[] mapping)
{
Expand Down Expand Up @@ -147,8 +150,10 @@ public unsafe int Decode(byte[] input, int inputLength, short[] output, int fram
/// Decodes a multistream Opus frame.
/// </summary>
/// <param name="input">Input in float format (interleaved if 2 channels), with a normal range of +/-1.0. Samples with a range beyond +/-1.0 are supported but will be clipped by decoders using the integer API and should only be used if it is known that the far end supports extended dynamic range. length is frame_size*channels*sizeof(float)</param>
/// <param name="frame_size">The number of samples per channel of available space in pcm. If this is less than the maximum packet duration (120 ms; 5760 for 48kHz), this function will not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), then frame_size needs to be exactly the duration of audio that is missing, otherwise the decoder will not be in the optimal state to decode the next incoming packet. For the PLC and FEC cases, frame_size must be a multiple of 2.5 ms.</param>
/// <param name="inputLength">The number of samples per channel of available space in pcm. If this is less than the maximum packet duration (120 ms; 5760 for 48kHz), this function will not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), then frame_size needs to be exactly the duration of audio that is missing, otherwise the decoder will not be in the optimal state to decode the next incoming packet. For the PLC and FEC cases, frame_size must be a multiple of 2.5 ms.</param>
/// <param name="output">Output signal, with interleaved samples. This must contain room for frame_size*channels samples.</param>
/// <param name="frame_size"></param>
/// <param name="decodeFEC">Flag (false or true) to request that any in-band forward error correction data be decoded. If no such data is available, the frame is decoded as if it were lost.</param>
/// <param name="inputOffset">Offset to start reading in the input.</param>
/// <param name="outputOffset">Offset to start writing in the output.</param>
/// <returns>The length of the decoded packet on success or a negative error code (see <see cref="Enums.OpusError"/>) on failure. Note: OpusSharp throws an error if there is a negative error code.</returns>
Expand Down Expand Up @@ -184,7 +189,6 @@ public void DecoderCtl(Enums.DecoderCtl ctl, int value)
/// Requests a CTL on the multistream decoder.
/// </summary>
/// <param name="ctl">The decoder CTL to request.</param>
/// <param name="value">The value that is outputted from the CTL.</param>
/// <exception cref="ObjectDisposedException"></exception>
/// <exception cref="OpusException"></exception>
public int DecoderCtl(Enums.DecoderCtl ctl)
Expand Down Expand Up @@ -223,6 +227,10 @@ public int DecoderCtl(Enums.GenericCtl ctl)
return val;
}

/// <summary>
/// Disposes the object.
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
if (disposing)
Expand Down
5 changes: 4 additions & 1 deletion OpusSharp.Core/OpusMSEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ public void EncoderCtl(Enums.EncoderCtl ctl, int value)
/// Requests a CTL on the encoder.
/// </summary>
/// <param name="ctl">The encoder CTL to request.</param>
/// <param name="value">The value that is outputted from the CTL.</param>
/// <exception cref="ObjectDisposedException"></exception>
/// <exception cref="OpusException"></exception>
public int EncoderCtl(Enums.EncoderCtl ctl)
Expand Down Expand Up @@ -304,6 +303,10 @@ public int EncoderCtl(Enums.GenericCtl ctl)
return val;
}

/// <summary>
/// Disposes the object.
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
if (disposing)
Expand Down
2 changes: 2 additions & 0 deletions OpusSharp.Core/OpusSharp.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
<TargetFrameworks>netstandard2.0;net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>

<PropertyGroup Condition="'$(IsWindows)'=='true'">
Expand Down
1 change: 1 addition & 0 deletions OpusSharp.Core/OpusSharp.Core.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
<files>
<file src="bin/Release/netstandard2.0/OpusSharp.dll" target="lib/netstandard2.0/OpusSharp.dll" />
<file src="bin/Release/netstandard2.0/OpusSharp.pdb" target="lib/netstandard2.0/OpusSharp.pdb" />
<file src="bin/Release/netstandard2.0/OpusSharp.xml" target="lib/netstandard2.0" />
</files>
</package>
4 changes: 4 additions & 0 deletions OpusSharp.Core/Repacketizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ private void ThrowIfDisposed()
}
}

/// <summary>
/// Disposes the object.
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
if (disposing)
Expand Down
19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# OpusSharp
OpusSharp aims to be a cross platform C# compatible version of the native opus codec/library. The code uses the native compiled DLL's with instructions on how to compile you're own. Currently Windows and Android binaries are only available.
OpusSharp aims to be a cross platform C# compatible version of the native opus codec/library. The code uses the native compiled DLL's with instructions on how to compile your own. Currently, Windows, Android, iOS and Linux binaries are available.

# Examples
Encoder:
Expand Down Expand Up @@ -60,28 +60,35 @@ var isUsingFec = Encoder.EncoderCtl(OpusSharp.Core.Enums.EncoderCtl.OPUS_GET_INB
Console.WriteLine(isUsingFec);
```

Example Usage in MAUI application providing support for android and windows: https://github.com/SineVector241/VoiceCraft-MCBE_Proximity_Chat

# Packaging as nuget
To use this library, you will need to package it so it can dynamically be loaded onto your project without having to declare or make your own library specific to a platform as that is handled by the nuget file.

First, Open the `.sln` file in an IDE of you're choice, then right click on the solution and build.
First, Open the `.sln` file in an IDE of your choice, then right click on the solution and build.

To package, Make sure to have nuget already installed either by an EXE in the same directory as this repository or install via PATH, Then just run `PackAll.bat`.

# Compiling Native Builds
Please check [OpusLibs](./OpusLibs) for more information.

# Using the nuget package
Just install it onto your directory, If you cannot find your package in the nuget package manager of your project, you will need to add you're local nuget feed to you're IDE: https://learn.microsoft.com/en-us/nuget/consume-packages/install-use-packages-visual-studio#package-sources
Just install it onto your directory, If you cannot find your package in the nuget package manager of your project, you will need to add your local nuget feed to your IDE: https://learn.microsoft.com/en-us/nuget/consume-packages/install-use-packages-visual-studio#package-sources

# Working And Tested
- OpusEncoder - Every function is working
- OpusDecoder - Every function is working except for Parse() function as that throws a System.EngineExecutionException, I don't know why...
- Android - arm64-v8a, armeabi-v7a, x86, x86_64.
- Windows - win-x64, win-x86
- iOS/MAC - All Architectures.

# Not Tested
- OpusMSEncoder
- OpusMSDecoder
- Repacketizer
- Windows - arm, arm64
- Linux - linux-x64

# Planned
- OpusInfo
- DredDecoder

# Compiling Native Builds
Please check [OpusLibs](./OpusLibs) for more information.

0 comments on commit 8cd596a

Please sign in to comment.