/CUETools.Codecs.libFLAC/FLACDLL.cs

https://github.com/gchudov/cuetools.net · C# · 180 lines · 132 code · 48 blank · 0 comment · 5 complexity · 44ba31e0a44e8c4d9bf36c94d84b56f8 MD5 · raw file

  1. using System;
  2. using System.Runtime.InteropServices;
  3. namespace CUETools.Codecs.libFLAC
  4. {
  5. internal unsafe static class FLACDLL
  6. {
  7. internal const string DllName = "libFLAC_dynamic";
  8. internal const CallingConvention libFLACCallingConvention = CallingConvention.Cdecl;
  9. internal const int FLAC__MAX_CHANNELS = 8;
  10. private static string version;
  11. internal static string GetVersion => version;
  12. [DllImport("kernel32.dll")]
  13. private static extern IntPtr LoadLibrary(string dllToLoad);
  14. [DllImport("kernel32.dll")]
  15. public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
  16. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  17. internal delegate FLAC__StreamDecoderReadStatus FLAC__StreamDecoderReadCallback(IntPtr decoder, byte* buffer, ref long bytes, void* client_data);
  18. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  19. internal delegate FLAC__StreamDecoderSeekStatus FLAC__StreamDecoderSeekCallback(IntPtr decoder, long absolute_byte_offset, void* client_data);
  20. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  21. internal delegate FLAC__StreamDecoderTellStatus FLAC__StreamDecoderTellCallback(IntPtr decoder, out long absolute_byte_offset, void* client_data);
  22. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  23. internal delegate FLAC__StreamDecoderLengthStatus FLAC__StreamDecoderLengthCallback(IntPtr decoder, out long stream_length, void* client_data);
  24. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  25. internal delegate int FLAC__StreamDecoderEofCallback(IntPtr decoder, void* client_data);
  26. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  27. internal delegate FLAC__StreamDecoderWriteStatus FLAC__StreamDecoderWriteCallback(IntPtr decoder, FLAC__Frame* frame, int** buffer, void* client_data);
  28. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  29. internal delegate void FLAC__StreamDecoderMetadataCallback(IntPtr decoder, FLAC__StreamMetadata* metadata, void* client_data);
  30. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  31. internal delegate void FLAC__StreamDecoderErrorCallback(IntPtr decoder, FLAC__StreamDecoderErrorStatus status, void* client_data);
  32. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  33. internal static extern IntPtr FLAC__stream_decoder_new();
  34. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  35. internal static extern int FLAC__stream_decoder_set_metadata_respond(IntPtr decoder, FLAC__MetadataType type);
  36. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  37. internal static extern int FLAC__stream_decoder_process_until_end_of_metadata(IntPtr decoder);
  38. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  39. internal static extern FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream(
  40. IntPtr decoder,
  41. FLAC__StreamDecoderReadCallback read_callback,
  42. FLAC__StreamDecoderSeekCallback seek_callback,
  43. FLAC__StreamDecoderTellCallback tell_callback,
  44. FLAC__StreamDecoderLengthCallback length_callback,
  45. FLAC__StreamDecoderEofCallback eof_callback,
  46. FLAC__StreamDecoderWriteCallback write_callback,
  47. FLAC__StreamDecoderMetadataCallback metadata_callback,
  48. FLAC__StreamDecoderErrorCallback error_callback,
  49. void* client_data
  50. );
  51. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  52. internal static extern int FLAC__stream_decoder_finish(IntPtr decoder);
  53. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  54. internal static extern int FLAC__stream_decoder_delete(IntPtr decoder);
  55. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  56. internal static extern int FLAC__stream_decoder_seek_absolute(IntPtr decoder, long sample);
  57. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  58. internal static extern FLAC__StreamDecoderState FLAC__stream_decoder_get_state(IntPtr decoder);
  59. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  60. internal static extern int FLAC__stream_decoder_process_single(IntPtr decoder);
  61. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  62. internal static extern IntPtr FLAC__stream_encoder_new();
  63. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  64. internal static extern int FLAC__stream_encoder_set_bits_per_sample(IntPtr encoder, uint value);
  65. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  66. internal static extern int FLAC__stream_encoder_set_sample_rate(IntPtr encoder, uint value);
  67. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  68. internal static extern int FLAC__stream_encoder_set_channels(IntPtr encoder, uint value);
  69. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  70. internal static extern int FLAC__stream_encoder_finish(IntPtr encoder);
  71. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  72. internal static extern int FLAC__stream_encoder_delete(IntPtr encoder);
  73. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  74. internal static extern int FLAC__stream_encoder_process_interleaved(IntPtr encoder, int* buffer, int samples);
  75. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  76. internal static extern FLAC__StreamEncoderState FLAC__stream_encoder_get_state(IntPtr encoder);
  77. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  78. internal static extern void FLAC__stream_encoder_get_verify_decoder_error_stats(IntPtr encoder, out ulong absolute_sample, out uint frame_number, out uint channel, out uint sample, out int expected, out int got);
  79. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  80. internal static extern FLAC__StreamMetadata* FLAC__metadata_object_new(FLAC__MetadataType type);
  81. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  82. internal static extern int FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(FLAC__StreamMetadata* metadata, int samples, long total_samples);
  83. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  84. internal static extern int FLAC__metadata_object_seektable_template_sort(FLAC__StreamMetadata* metadata, int compact);
  85. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  86. internal static extern int FLAC__stream_encoder_set_metadata(IntPtr encoder, FLAC__StreamMetadata** metadata, int num_blocks);
  87. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  88. internal static extern int FLAC__stream_encoder_set_verify(IntPtr encoder, int value);
  89. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  90. internal static extern int FLAC__stream_encoder_set_do_md5(IntPtr encoder, int value);
  91. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  92. internal static extern int FLAC__stream_encoder_set_total_samples_estimate(IntPtr encoder, long value);
  93. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  94. internal static extern int FLAC__stream_encoder_set_compression_level(IntPtr encoder, int value);
  95. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  96. internal static extern int FLAC__stream_encoder_set_blocksize(IntPtr encoder, int value);
  97. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  98. internal delegate FLAC__StreamEncoderWriteStatus FLAC__StreamEncoderWriteCallback(IntPtr encoder, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] buffer, long bytes, int samples, int current_frame, void* client_data);
  99. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  100. internal delegate FLAC__StreamEncoderSeekStatus FLAC__StreamEncoderSeekCallback(IntPtr encoder, long absolute_byte_offset, void* client_data);
  101. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  102. internal delegate FLAC__StreamEncoderTellStatus FLAC__StreamEncoderTellCallback(IntPtr encoder, out long absolute_byte_offset, void* client_data);
  103. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  104. internal delegate void FLAC__StreamEncoderMetadataCallback(IntPtr encoder, FLAC__StreamMetadata* metadata, void* client_data);
  105. [DllImport(DllName, CallingConvention = libFLACCallingConvention)]
  106. internal static extern FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_stream(IntPtr encoder,
  107. FLAC__StreamEncoderWriteCallback write_callback,
  108. FLAC__StreamEncoderSeekCallback seek_callback,
  109. FLAC__StreamEncoderTellCallback tell_callback,
  110. FLAC__StreamEncoderMetadataCallback metadata_callback,
  111. void* client_data);
  112. static FLACDLL()
  113. {
  114. var myPath = new Uri(typeof(FLACDLL).Assembly.CodeBase).LocalPath;
  115. var myFolder = System.IO.Path.GetDirectoryName(myPath);
  116. var is64 = IntPtr.Size == 8;
  117. var subfolder = is64 ? "x64" : "win32";
  118. #if NET47
  119. IntPtr Dll = LoadLibrary(System.IO.Path.Combine(myFolder, subfolder, DllName + ".dll"));
  120. #else
  121. IntPtr Dll = LoadLibrary(System.IO.Path.Combine(System.IO.Path.Combine(myFolder, subfolder), DllName + ".dll"));
  122. #endif
  123. if (Dll == IntPtr.Zero)
  124. Dll = LoadLibrary(DllName + ".dll");
  125. if (Dll == IntPtr.Zero)
  126. throw new DllNotFoundException();
  127. IntPtr addr = GetProcAddress(Dll, "FLAC__VERSION_STRING");
  128. IntPtr ptr = Marshal.ReadIntPtr(addr);
  129. version = Marshal.PtrToStringAnsi(ptr);
  130. }
  131. };
  132. }