Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add AudioOptions class #978

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
9 changes: 2 additions & 7 deletions Plugin~/WebRTCPlugin/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,9 @@ namespace webrtc
// todo:(kazuki)
}

rtc::scoped_refptr<AudioSourceInterface> Context::CreateAudioSource()
rtc::scoped_refptr<AudioSourceInterface> Context::CreateAudioSource(const cricket::AudioOptions& options)
{
// avoid optimization specially for voice
cricket::AudioOptions audioOptions;
audioOptions.auto_gain_control = false;
audioOptions.noise_suppression = false;
audioOptions.highpass_filter = false;
return UnityAudioTrackSource::Create(audioOptions);
return UnityAudioTrackSource::Create(options);
}

rtc::scoped_refptr<AudioTrackInterface>
Expand Down
2 changes: 1 addition & 1 deletion Plugin~/WebRTCPlugin/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ namespace webrtc
MediaStreamObserver* GetObserver(const webrtc::MediaStreamInterface* stream);

// Audio Source
rtc::scoped_refptr<AudioSourceInterface> CreateAudioSource();
rtc::scoped_refptr<AudioSourceInterface> CreateAudioSource(const cricket::AudioOptions& options);
// Audio Renderer
AudioTrackSinkAdapter* CreateAudioTrackSinkAdapter();
void DeleteAudioTrackSinkAdapter(AudioTrackSinkAdapter* sink);
Expand Down
30 changes: 28 additions & 2 deletions Plugin~/WebRTCPlugin/WebRTCPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,35 @@ extern "C"
return source.get();
}

UNITY_INTERFACE_EXPORT webrtc::AudioSourceInterface* ContextCreateAudioTrackSource(Context* context)
struct AudioOptions
{
rtc::scoped_refptr<AudioSourceInterface> source = context->CreateAudioSource();
Optional<bool> echoCancellation;
Optional<bool> autoGainControl;
Optional<bool> noiseSuppression;
Optional<bool> highpassFilter;

operator cricket::AudioOptions() const
{
cricket::AudioOptions dst = {};
dst.echo_cancellation = static_cast<absl::optional<bool>>(echoCancellation);
dst.auto_gain_control = static_cast<absl::optional<bool>>(autoGainControl);
dst.noise_suppression = static_cast<absl::optional<bool>>(noiseSuppression);
dst.highpass_filter = static_cast<absl::optional<bool>>(highpassFilter);
#if defined(WEBRTC_IOS)
if (dst.echo_cancellation && dst.echo_cancellation.value())
{
dst.ios_force_software_aec_HACK = true;
}
#endif
return dst;
}
};

UNITY_INTERFACE_EXPORT webrtc::AudioSourceInterface*
ContextCreateAudioTrackSource(Context* context, const AudioOptions* options)
{
cricket::AudioOptions _options = *options;
rtc::scoped_refptr<AudioSourceInterface> source = context->CreateAudioSource(_options);
context->AddRefPtr(source);
return source.get();
}
Expand Down
4 changes: 2 additions & 2 deletions Plugin~/WebRTCPluginTest/ContextTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ namespace webrtc

TEST_P(ContextTest, CreateAndDeleteAudioTrack)
{
const auto source = context->CreateAudioSource();
const auto source = context->CreateAudioSource(cricket::AudioOptions());
EXPECT_NE(nullptr, source);
const auto track = context->CreateAudioTrack("audio", source.get());
EXPECT_NE(nullptr, track);
Expand All @@ -95,7 +95,7 @@ namespace webrtc
{
const auto stream = context->CreateMediaStream("audiostream");
EXPECT_NE(nullptr, stream);
const auto source = context->CreateAudioSource();
const auto source = context->CreateAudioSource(cricket::AudioOptions());
EXPECT_NE(nullptr, source);
const auto track = context->CreateAudioTrack("audio", source.get());
EXPECT_NE(nullptr, track);
Expand Down
67 changes: 60 additions & 7 deletions Runtime/Scripts/AudioStreamTrack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,32 @@ public static void SetTrack(this AudioSource source, AudioStreamTrack track)
}
}

/// <summary>
///
/// </summary>
public class AudioOptions
{
/// <summary>
///
/// </summary>
public bool? echoCancellation;
/// <summary>
///
/// </summary>
public bool? autoGainControl;

/// <summary>
///
/// </summary>
public bool? noiseSuppression;

/// <summary>
///
/// </summary>
public bool? highpassFilter;

}

/// <summary>
///
/// </summary>
Expand Down Expand Up @@ -184,17 +210,17 @@ internal void SetData(float[] data, int channels, int sampleRate)
/// <summary>
///
/// </summary>
public AudioStreamTrack()
: this(Guid.NewGuid().ToString(), new AudioTrackSource())
public AudioStreamTrack(AudioOptions options = null)
: this(Guid.NewGuid().ToString(), new AudioTrackSource(options))
{
}

/// <summary>
///
/// </summary>
/// <param name="source"></param>
public AudioStreamTrack(AudioSource source)
: this(Guid.NewGuid().ToString(), new AudioTrackSource())
public AudioStreamTrack(AudioSource source, AudioOptions options = null)
: this(Guid.NewGuid().ToString(), new AudioTrackSource(options))
{
if (source == null)
throw new ArgumentNullException("source", "AudioSource argument is null.");
Expand All @@ -206,8 +232,8 @@ public AudioStreamTrack(AudioSource source)
_audioCapturer.sender = true;
}

public AudioStreamTrack(AudioListener listener)
: this(Guid.NewGuid().ToString(), new AudioTrackSource())
public AudioStreamTrack(AudioListener listener, AudioOptions options = null)
: this(Guid.NewGuid().ToString(), new AudioTrackSource(options))
{
if (listener == null)
throw new ArgumentNullException("listener", "AudioListener argument is null.");
Expand Down Expand Up @@ -369,13 +395,40 @@ public event AudioReadEventHandler onReceived
}
}

[StructLayout(LayoutKind.Sequential)]
internal struct AudioOptionsInternal
{
public OptionalBool echoCancellation;
public OptionalBool autoGainControl;
public OptionalBool noiseSuppression;
public OptionalBool highpassFilter;

public static explicit operator AudioOptionsInternal(AudioOptions origin)
{
AudioOptionsInternal dst = new AudioOptionsInternal
{
echoCancellation = origin.echoCancellation,
autoGainControl = origin.autoGainControl,
noiseSuppression = origin.noiseSuppression,
highpassFilter = origin.highpassFilter
};
return dst;
}
}

internal class AudioTrackSource : RefCountedObject
{
public AudioTrackSource() : base(WebRTC.Context.CreateAudioTrackSource())
public AudioTrackSource(AudioOptions options = null) : base(CreateAudioTrackSource(options))
{
WebRTC.Table.Add(self, this);
}

static IntPtr CreateAudioTrackSource(AudioOptions options)
{
var _options = options == null ? new AudioOptionsInternal() : (AudioOptionsInternal)options;
return WebRTC.Context.CreateAudioTrackSource(ref _options);
}

~AudioTrackSource()
{
this.Dispose();
Expand Down
4 changes: 2 additions & 2 deletions Runtime/Scripts/Context.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,9 +325,9 @@ public IntPtr CreateVideoTrackSource()
return NativeMethods.ContextCreateVideoTrackSource(self);
}

public IntPtr CreateAudioTrackSource()
public IntPtr CreateAudioTrackSource(ref AudioOptionsInternal options)
{
return NativeMethods.ContextCreateAudioTrackSource(self);
return NativeMethods.ContextCreateAudioTrackSource(self, ref options);
}

public IntPtr CreateAudioTrack(string label, IntPtr trackSource)
Expand Down
2 changes: 1 addition & 1 deletion Runtime/Scripts/WebRTC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1277,7 +1277,7 @@ public static extern void RegisterDebugLog(DelegateDebugLog func, [MarshalAs(Unm
[DllImport(WebRTC.Lib)]
public static extern void ContextDeleteDataChannel(IntPtr ptr, IntPtr ptrChannel);
[DllImport(WebRTC.Lib)]
public static extern IntPtr ContextCreateAudioTrackSource(IntPtr ptr);
public static extern IntPtr ContextCreateAudioTrackSource(IntPtr ptr, ref AudioOptionsInternal options);
[DllImport(WebRTC.Lib)]
public static extern IntPtr ContextCreateVideoTrackSource(IntPtr ptr);
[DllImport(WebRTC.Lib)]
Expand Down
3 changes: 2 additions & 1 deletion Tests/Runtime/ContextTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ public void CreateAndDeleteDataChannel()
public void CreateAndDeleteAudioTrack()
{
var context = WebRTC.Context;
var source = context.CreateAudioTrackSource();
var options = new AudioOptionsInternal();
var source = context.CreateAudioTrackSource(ref options);
var track = context.CreateAudioTrack("audio", source);
context.DeleteRefPtr(track);
context.DeleteRefPtr(source);
Expand Down
6 changes: 4 additions & 2 deletions Tests/Runtime/NativeAPITest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ public void AddAndRemoveVideoTrackToMediaStream()
public void AddAndRemoveAudioTrackToMediaStream()
{
var stream = NativeMethods.ContextCreateMediaStream(context, "MediaStream");
var source = NativeMethods.ContextCreateAudioTrackSource(context);
var options = new AudioOptionsInternal();
var source = NativeMethods.ContextCreateAudioTrackSource(context, ref options);
var track = NativeMethods.ContextCreateAudioTrack(context, "audio", source);
NativeMethods.MediaStreamAddTrack(stream, track);

Expand Down Expand Up @@ -262,7 +263,8 @@ public void AddAndRemoveAudioTrack()
var stream = NativeMethods.ContextCreateMediaStream(context, "MediaStream");
var streamId = NativeMethods.MediaStreamGetID(stream).AsAnsiStringWithFreeMem();
Assert.IsNotEmpty(streamId);
var source = NativeMethods.ContextCreateAudioTrackSource(context);
var options = new AudioOptionsInternal();
var source = NativeMethods.ContextCreateAudioTrackSource(context, ref options);
var track = NativeMethods.ContextCreateAudioTrack(context, "audio", source);
var error = NativeMethods.PeerConnectionAddTrack(peer, track, streamId, out var sender);
Assert.That(error, Is.EqualTo(RTCErrorType.None));
Expand Down