Skip to content

Commit

Permalink
feat: validate availability of native Windows libraries
Browse files Browse the repository at this point in the history
Validate whether the native libraries and their linked dependencies (e.g., MSVC runtime) are available and throw helpful error in case something is missing.
  • Loading branch information
protyposis committed Dec 9, 2023
1 parent 5908909 commit 55db90b
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/Aurio.FFmpeg/FFmpegAudioStreamFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ namespace Aurio.FFmpeg
{
public class FFmpegAudioStreamFactory : IAudioStreamFactory
{
public FFmpegAudioStreamFactory()
{
FFmpegReader.ValidateNativeLibraryAvailability();
}

public IAudioStream OpenFile(FileInfo fileInfo, FileInfo proxyFileInfo = null)
{
if (FFmpegSourceStream.WaveProxySuggested(fileInfo))
Expand Down
34 changes: 34 additions & 0 deletions src/Aurio.FFmpeg/FFmpegReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public class FFmpegReader : IDisposable
/// <param name="mode">the types of data to read</param>
public FFmpegReader(string filename, Type mode)
{
ValidateNativeLibraryAvailability();

this.filename = filename;
this.mode = mode;

Expand Down Expand Up @@ -75,6 +77,8 @@ public FFmpegReader(FileInfo fileInfo, Type mode)
/// <param name="fileName">optional filename as a hint for FFmpeg to determine the data format</param>
public FFmpegReader(Stream stream, Type mode, string fileName)
{
ValidateNativeLibraryAvailability();

this.filename = fileName ?? "bufferedIO_stream";
this.mode = mode;

Expand Down Expand Up @@ -131,6 +135,36 @@ public FFmpegReader(Stream stream, Type mode, string fileName)
public FFmpegReader(Stream stream, Type mode)
: this(stream, mode, null) { }

public static void ValidateNativeLibraryAvailability()
{
IntPtr dummyInstance = Marshal.AllocHGlobal(100);

try
{
// This can be any native invocation
InteropWrapper.stream_has_error(dummyInstance);
}
catch (DllNotFoundException e)
{
if (OperatingSystem.IsWindows())
{
throw new DllNotFoundException(
"The native FFmpeg proxy library cannot be loaded. Please make sure that the "
+ "Microsoft Visual C++ Redistributable for Visual Studio 2015 (or later) is installed.",
e
);
}
else
{
throw;
}
}
finally
{
Marshal.FreeHGlobal(dummyInstance);
}
}

private void CheckAndHandleOpeningError()
{
if (InteropWrapper.stream_has_error(instance))
Expand Down
5 changes: 5 additions & 0 deletions src/Aurio.Soxr/ResamplerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ namespace Aurio.Soxr
{
public class ResamplerFactory : IResamplerFactory
{
public ResamplerFactory()
{
SoxResampler.ValidateNativeLibraryAvailability();
}

public IResampler CreateInstance(
ResamplingQuality quality,
int channels,
Expand Down
26 changes: 26 additions & 0 deletions src/Aurio.Soxr/SoxResampler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public class SoxResampler : IDisposable
QualityFlags qualityFlags
)
{
ValidateNativeLibraryAvailability();

if (inputRate <= 0 || outputRate <= 0 || channels <= 0)
{
throw new SoxrException("one or more parameters are invalid (zero or negative)");
Expand Down Expand Up @@ -133,6 +135,30 @@ public SoxResampler(double inputRate, double outputRate, int channels)
QualityFlags.SOXR_ROLLOFF_SMALL
) { }

public static void ValidateNativeLibraryAvailability()
{
try
{
// This can be any native invocation
InteropWrapper.soxr_version();
}
catch (DllNotFoundException e)
{
if (OperatingSystem.IsWindows())
{
throw new DllNotFoundException(
"The native Soxr library cannot be loaded. Please make sure that the "
+ "Microsoft Visual C++ Redistributable for Visual Studio 2015 (or later) is installed.",
e
);
}
else
{
throw;
}
}
}

/// <summary>
/// Returns the libsoxr version.
/// </summary>
Expand Down

0 comments on commit 55db90b

Please sign in to comment.