windows-imports.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. #define NO_MIN_MAX 1
  2. #define WIN32_LEAN_AND_MEAN
  3. #include <windows.h>
  4. #include <ShlObj.h>
  5. #include <util/dstr.h>
  6. typedef unsigned long UInt32;
  7. typedef signed long SInt32;
  8. typedef signed long long SInt64;
  9. typedef double Float64;
  10. typedef SInt32 OSStatus;
  11. typedef unsigned char Boolean;
  12. typedef UInt32 AudioFormatPropertyID;
  13. enum { kVariableLengthArray = 1,
  14. };
  15. struct OpaqueAudioConverter;
  16. typedef struct OpaqueAudioConverter *AudioConverterRef;
  17. typedef UInt32 AudioConverterPropertyID;
  18. struct AudioValueRange {
  19. Float64 mMinimum;
  20. Float64 mMaximum;
  21. };
  22. typedef struct AudioValueRange AudioValueRange;
  23. struct AudioBuffer {
  24. UInt32 mNumberChannels;
  25. UInt32 mDataByteSize;
  26. void *mData;
  27. };
  28. typedef struct AudioBuffer AudioBuffer;
  29. struct AudioBufferList {
  30. UInt32 mNumberBuffers;
  31. AudioBuffer mBuffers[kVariableLengthArray];
  32. };
  33. typedef struct AudioBufferList AudioBufferList;
  34. struct AudioStreamBasicDescription {
  35. Float64 mSampleRate;
  36. UInt32 mFormatID;
  37. UInt32 mFormatFlags;
  38. UInt32 mBytesPerPacket;
  39. UInt32 mFramesPerPacket;
  40. UInt32 mBytesPerFrame;
  41. UInt32 mChannelsPerFrame;
  42. UInt32 mBitsPerChannel;
  43. UInt32 mReserved;
  44. };
  45. typedef struct AudioStreamBasicDescription AudioStreamBasicDescription;
  46. struct AudioStreamPacketDescription {
  47. SInt64 mStartOffset;
  48. UInt32 mVariableFramesInPacket;
  49. UInt32 mDataByteSize;
  50. };
  51. typedef struct AudioStreamPacketDescription AudioStreamPacketDescription;
  52. typedef OSStatus (*AudioConverterComplexInputDataProc)(
  53. AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets,
  54. AudioBufferList *ioData,
  55. AudioStreamPacketDescription **outDataPacketDescription,
  56. void *inUserData);
  57. enum { kAudioCodecPropertyNameCFString = 'lnam',
  58. kAudioCodecPropertyManufacturerCFString = 'lmak',
  59. kAudioCodecPropertyFormatCFString = 'lfor',
  60. //kAudioCodecPropertyHasVariablePacketByteSizes = 'vpk?',
  61. kAudioCodecPropertySupportedInputFormats = 'ifm#',
  62. kAudioCodecPropertySupportedOutputFormats = 'ofm#',
  63. kAudioCodecPropertyAvailableInputSampleRates = 'aisr',
  64. kAudioCodecPropertyAvailableOutputSampleRates = 'aosr',
  65. kAudioCodecPropertyAvailableBitRateRange = 'abrt',
  66. kAudioCodecPropertyMinimumNumberInputPackets = 'mnip',
  67. kAudioCodecPropertyMinimumNumberOutputPackets = 'mnop',
  68. kAudioCodecPropertyAvailableNumberChannels = 'cmnc',
  69. kAudioCodecPropertyDoesSampleRateConversion = 'lmrc',
  70. kAudioCodecPropertyAvailableInputChannelLayoutTags = 'aicl',
  71. kAudioCodecPropertyAvailableOutputChannelLayoutTags = 'aocl',
  72. kAudioCodecPropertyInputFormatsForOutputFormat = 'if4o',
  73. kAudioCodecPropertyOutputFormatsForInputFormat = 'of4i',
  74. kAudioCodecPropertyFormatInfo = 'acfi',
  75. };
  76. enum { kAudioCodecPropertyInputBufferSize = 'tbuf',
  77. kAudioCodecPropertyPacketFrameSize = 'pakf',
  78. kAudioCodecPropertyMaximumPacketByteSize = 'pakb',
  79. kAudioCodecPropertyCurrentInputFormat = 'ifmt',
  80. kAudioCodecPropertyCurrentOutputFormat = 'ofmt',
  81. kAudioCodecPropertyMagicCookie = 'kuki',
  82. kAudioCodecPropertyUsedInputBufferSize = 'ubuf',
  83. kAudioCodecPropertyIsInitialized = 'init',
  84. kAudioCodecPropertyCurrentTargetBitRate = 'brat',
  85. kAudioCodecPropertyCurrentInputSampleRate = 'cisr',
  86. kAudioCodecPropertyCurrentOutputSampleRate = 'cosr',
  87. kAudioCodecPropertyQualitySetting = 'srcq',
  88. kAudioCodecPropertyApplicableBitRateRange = 'brta',
  89. kAudioCodecPropertyApplicableInputSampleRates = 'isra',
  90. kAudioCodecPropertyApplicableOutputSampleRates = 'osra',
  91. kAudioCodecPropertyPaddedZeros = 'pad0',
  92. kAudioCodecPropertyPrimeMethod = 'prmm',
  93. kAudioCodecPropertyPrimeInfo = 'prim',
  94. kAudioCodecPropertyCurrentInputChannelLayout = 'icl ',
  95. kAudioCodecPropertyCurrentOutputChannelLayout = 'ocl ',
  96. kAudioCodecPropertySettings = 'acs ',
  97. kAudioCodecPropertyFormatList = 'acfl',
  98. kAudioCodecPropertyBitRateControlMode = 'acbf',
  99. kAudioCodecPropertySoundQualityForVBR = 'vbrq',
  100. kAudioCodecPropertyMinimumDelayMode = 'mdel' };
  101. enum { kAudioCodecBitRateControlMode_Constant = 0,
  102. kAudioCodecBitRateControlMode_LongTermAverage = 1,
  103. kAudioCodecBitRateControlMode_VariableConstrained = 2,
  104. kAudioCodecBitRateControlMode_Variable = 3,
  105. };
  106. enum { kAudioFormatLinearPCM = 'lpcm',
  107. kAudioFormatAC3 = 'ac-3',
  108. kAudioFormat60958AC3 = 'cac3',
  109. kAudioFormatAppleIMA4 = 'ima4',
  110. kAudioFormatMPEG4AAC = 'aac ',
  111. kAudioFormatMPEG4CELP = 'celp',
  112. kAudioFormatMPEG4HVXC = 'hvxc',
  113. kAudioFormatMPEG4TwinVQ = 'twvq',
  114. kAudioFormatMACE3 = 'MAC3',
  115. kAudioFormatMACE6 = 'MAC6',
  116. kAudioFormatULaw = 'ulaw',
  117. kAudioFormatALaw = 'alaw',
  118. kAudioFormatQDesign = 'QDMC',
  119. kAudioFormatQDesign2 = 'QDM2',
  120. kAudioFormatQUALCOMM = 'Qclp',
  121. kAudioFormatMPEGLayer1 = '.mp1',
  122. kAudioFormatMPEGLayer2 = '.mp2',
  123. kAudioFormatMPEGLayer3 = '.mp3',
  124. kAudioFormatTimeCode = 'time',
  125. kAudioFormatMIDIStream = 'midi',
  126. kAudioFormatParameterValueStream = 'apvs',
  127. kAudioFormatAppleLossless = 'alac',
  128. kAudioFormatMPEG4AAC_HE = 'aach',
  129. kAudioFormatMPEG4AAC_LD = 'aacl',
  130. kAudioFormatMPEG4AAC_ELD = 'aace',
  131. kAudioFormatMPEG4AAC_ELD_SBR = 'aacf',
  132. kAudioFormatMPEG4AAC_ELD_V2 = 'aacg',
  133. kAudioFormatMPEG4AAC_HE_V2 = 'aacp',
  134. kAudioFormatMPEG4AAC_Spatial = 'aacs',
  135. kAudioFormatAMR = 'samr',
  136. kAudioFormatAudible = 'AUDB',
  137. kAudioFormatiLBC = 'ilbc',
  138. kAudioFormatDVIIntelIMA = 0x6D730011,
  139. kAudioFormatMicrosoftGSM = 0x6D730031,
  140. kAudioFormatAES3 = 'aes3',
  141. };
  142. enum { kAudioFormatFlagIsFloat = (1L << 0),
  143. kAudioFormatFlagIsBigEndian = (1L << 1),
  144. kAudioFormatFlagIsSignedInteger = (1L << 2),
  145. kAudioFormatFlagIsPacked = (1L << 3),
  146. kAudioFormatFlagIsAlignedHigh = (1L << 4),
  147. kAudioFormatFlagIsNonInterleaved = (1L << 5),
  148. kAudioFormatFlagIsNonMixable = (1L << 6),
  149. kAudioFormatFlagsAreAllClear = (1L << 31),
  150. kLinearPCMFormatFlagIsFloat = kAudioFormatFlagIsFloat,
  151. kLinearPCMFormatFlagIsBigEndian = kAudioFormatFlagIsBigEndian,
  152. kLinearPCMFormatFlagIsSignedInteger = kAudioFormatFlagIsSignedInteger,
  153. kLinearPCMFormatFlagIsPacked = kAudioFormatFlagIsPacked,
  154. kLinearPCMFormatFlagIsAlignedHigh = kAudioFormatFlagIsAlignedHigh,
  155. kLinearPCMFormatFlagIsNonInterleaved = kAudioFormatFlagIsNonInterleaved,
  156. kLinearPCMFormatFlagIsNonMixable = kAudioFormatFlagIsNonMixable,
  157. kLinearPCMFormatFlagsAreAllClear = kAudioFormatFlagsAreAllClear,
  158. kAppleLosslessFormatFlag_16BitSourceData = 1,
  159. kAppleLosslessFormatFlag_20BitSourceData = 2,
  160. kAppleLosslessFormatFlag_24BitSourceData = 3,
  161. kAppleLosslessFormatFlag_32BitSourceData = 4,
  162. };
  163. enum { kAudioFormatFlagsNativeEndian = 0 };
  164. enum {
  165. // AudioStreamBasicDescription structure properties
  166. kAudioFormatProperty_FormatInfo = 'fmti',
  167. kAudioFormatProperty_FormatName = 'fnam',
  168. kAudioFormatProperty_EncodeFormatIDs = 'acof',
  169. kAudioFormatProperty_DecodeFormatIDs = 'acif',
  170. kAudioFormatProperty_FormatList = 'flst',
  171. kAudioFormatProperty_ASBDFromESDS = 'essd',
  172. kAudioFormatProperty_ChannelLayoutFromESDS = 'escl',
  173. kAudioFormatProperty_OutputFormatList = 'ofls',
  174. kAudioFormatProperty_Encoders = 'aven',
  175. kAudioFormatProperty_Decoders = 'avde',
  176. kAudioFormatProperty_FormatIsVBR = 'fvbr',
  177. kAudioFormatProperty_FormatIsExternallyFramed = 'fexf',
  178. kAudioFormatProperty_AvailableEncodeBitRates = 'aebr',
  179. kAudioFormatProperty_AvailableEncodeSampleRates = 'aesr',
  180. kAudioFormatProperty_AvailableEncodeChannelLayoutTags = 'aecl',
  181. kAudioFormatProperty_AvailableEncodeNumberChannels = 'avnc',
  182. kAudioFormatProperty_ASBDFromMPEGPacket = 'admp',
  183. //
  184. // AudioChannelLayout structure properties
  185. kAudioFormatProperty_BitmapForLayoutTag = 'bmtg',
  186. kAudioFormatProperty_MatrixMixMap = 'mmap',
  187. kAudioFormatProperty_ChannelMap = 'chmp',
  188. kAudioFormatProperty_NumberOfChannelsForLayout = 'nchm',
  189. kAudioFormatProperty_ValidateChannelLayout = 'vacl',
  190. kAudioFormatProperty_ChannelLayoutForTag = 'cmpl',
  191. kAudioFormatProperty_TagForChannelLayout = 'cmpt',
  192. kAudioFormatProperty_ChannelLayoutName = 'lonm',
  193. kAudioFormatProperty_ChannelLayoutSimpleName = 'lsnm',
  194. kAudioFormatProperty_ChannelLayoutForBitmap = 'cmpb',
  195. kAudioFormatProperty_ChannelName = 'cnam',
  196. kAudioFormatProperty_ChannelShortName = 'csnm',
  197. kAudioFormatProperty_TagsForNumberOfChannels = 'tagc',
  198. kAudioFormatProperty_PanningMatrix = 'panm',
  199. kAudioFormatProperty_BalanceFade = 'balf',
  200. //
  201. // ID3 tag (MP3 metadata) properties
  202. kAudioFormatProperty_ID3TagSize = 'id3s',
  203. kAudioFormatProperty_ID3TagToDictionary = 'id3d',
  204. };
  205. enum { kAudioConverterPropertyMinimumInputBufferSize = 'mibs',
  206. kAudioConverterPropertyMinimumOutputBufferSize = 'mobs',
  207. kAudioConverterPropertyMaximumInputBufferSize = 'xibs',
  208. kAudioConverterPropertyMaximumInputPacketSize = 'xips',
  209. kAudioConverterPropertyMaximumOutputPacketSize = 'xops',
  210. kAudioConverterPropertyCalculateInputBufferSize = 'cibs',
  211. kAudioConverterPropertyCalculateOutputBufferSize = 'cobs',
  212. kAudioConverterPropertyInputCodecParameters = 'icdp',
  213. kAudioConverterPropertyOutputCodecParameters = 'ocdp',
  214. kAudioConverterSampleRateConverterAlgorithm = 'srci',
  215. kAudioConverterSampleRateConverterComplexity = 'srca',
  216. kAudioConverterSampleRateConverterQuality = 'srcq',
  217. kAudioConverterSampleRateConverterInitialPhase = 'srcp',
  218. kAudioConverterCodecQuality = 'cdqu',
  219. kAudioConverterPrimeMethod = 'prmm',
  220. kAudioConverterPrimeInfo = 'prim',
  221. kAudioConverterChannelMap = 'chmp',
  222. kAudioConverterDecompressionMagicCookie = 'dmgc',
  223. kAudioConverterCompressionMagicCookie = 'cmgc',
  224. kAudioConverterEncodeBitRate = 'brat',
  225. kAudioConverterEncodeAdjustableSampleRate = 'ajsr',
  226. kAudioConverterInputChannelLayout = 'icl ',
  227. kAudioConverterOutputChannelLayout = 'ocl ',
  228. kAudioConverterApplicableEncodeBitRates = 'aebr',
  229. kAudioConverterAvailableEncodeBitRates = 'vebr',
  230. kAudioConverterApplicableEncodeSampleRates = 'aesr',
  231. kAudioConverterAvailableEncodeSampleRates = 'vesr',
  232. kAudioConverterAvailableEncodeChannelLayoutTags = 'aecl',
  233. kAudioConverterCurrentOutputStreamDescription = 'acod',
  234. kAudioConverterCurrentInputStreamDescription = 'acid',
  235. kAudioConverterPropertySettings = 'acps',
  236. kAudioConverterPropertyBitDepthHint = 'acbd',
  237. kAudioConverterPropertyFormatList = 'flst',
  238. };
  239. enum { kAudioConverterQuality_Max = 0x7F,
  240. kAudioConverterQuality_High = 0x60,
  241. kAudioConverterQuality_Medium = 0x40,
  242. kAudioConverterQuality_Low = 0x20,
  243. kAudioConverterQuality_Min = 0,
  244. };
  245. enum { kAudio_UnimplementedError = -4,
  246. kAudio_FileNotFoundError = -43,
  247. kAudio_FilePermissionError = -54,
  248. kAudio_TooManyFilesOpenError = -42,
  249. kAudio_BadFilePathError = '!pth', // 0x21707468, 561017960
  250. kAudio_ParamError = -50,
  251. kAudio_MemFullError = -108,
  252. kAudioConverterErr_FormatNotSupported = 'fmt?',
  253. kAudioConverterErr_OperationNotSupported = 0x6F703F3F,
  254. // 'op??', integer used because of trigraph
  255. kAudioConverterErr_PropertyNotSupported = 'prop',
  256. kAudioConverterErr_InvalidInputSize = 'insz',
  257. kAudioConverterErr_InvalidOutputSize = 'otsz',
  258. // e.g. byte size is not a multiple of the frame size
  259. kAudioConverterErr_UnspecifiedError = 'what',
  260. kAudioConverterErr_BadPropertySizeError = '!siz',
  261. kAudioConverterErr_RequiresPacketDescriptionsError = '!pkd',
  262. kAudioConverterErr_InputSampleRateOutOfRange = '!isr',
  263. kAudioConverterErr_OutputSampleRateOutOfRange = '!osr',
  264. };
  265. typedef OSStatus (*AudioConverterNew_t)(
  266. const AudioStreamBasicDescription *inSourceFormat,
  267. const AudioStreamBasicDescription *inDestinationFormat,
  268. AudioConverterRef *outAudioConverter);
  269. typedef OSStatus (*AudioConverterDispose_t)(AudioConverterRef inAudioConverter);
  270. typedef OSStatus (*AudioConverterReset_t)(AudioConverterRef inAudioConverter);
  271. typedef OSStatus (*AudioConverterGetProperty_t)(
  272. AudioConverterRef inAudioConverter,
  273. AudioConverterPropertyID inPropertyID, UInt32 *ioPropertyDataSize,
  274. void *outPropertyData);
  275. typedef OSStatus (*AudioConverterGetPropertyInfo_t)(
  276. AudioConverterRef inAudioConverter,
  277. AudioConverterPropertyID inPropertyID, UInt32 *outSize,
  278. Boolean *outWritable);
  279. typedef OSStatus (*AudioConverterSetProperty_t)(
  280. AudioConverterRef inAudioConverter,
  281. AudioConverterPropertyID inPropertyID, UInt32 inPropertyDataSize,
  282. const void *inPropertyData);
  283. typedef OSStatus (*AudioConverterFillComplexBuffer_t)(
  284. AudioConverterRef inAudioConverter,
  285. AudioConverterComplexInputDataProc inInputDataProc,
  286. void *inInputDataProcUserData, UInt32 *ioOutputDataPacketSize,
  287. AudioBufferList *outOutputData,
  288. AudioStreamPacketDescription *outPacketDescription);
  289. typedef OSStatus (*AudioFormatGetProperty_t)(AudioFormatPropertyID inPropertyID,
  290. UInt32 inSpecifierSize,
  291. const void *inSpecifier,
  292. UInt32 *ioPropertyDataSize,
  293. void *outPropertyData);
  294. typedef OSStatus (*AudioFormatGetPropertyInfo_t)(
  295. AudioFormatPropertyID inPropertyID, UInt32 inSpecifierSize,
  296. const void *inSpecifier, UInt32 *outPropertyDataSize);
  297. static AudioConverterNew_t AudioConverterNew = NULL;
  298. static AudioConverterDispose_t AudioConverterDispose = NULL;
  299. static AudioConverterReset_t AudioConverterReset = NULL;
  300. static AudioConverterGetProperty_t AudioConverterGetProperty = NULL;
  301. static AudioConverterGetPropertyInfo_t AudioConverterGetPropertyInfo = NULL;
  302. static AudioConverterSetProperty_t AudioConverterSetProperty = NULL;
  303. static AudioConverterFillComplexBuffer_t AudioConverterFillComplexBuffer = NULL;
  304. static AudioFormatGetProperty_t AudioFormatGetProperty = NULL;
  305. static AudioFormatGetPropertyInfo_t AudioFormatGetPropertyInfo = NULL;
  306. static HMODULE audio_toolbox = NULL;
  307. static void release_lib(void)
  308. {
  309. #define RELEASE_LIB(x) \
  310. if (x) { \
  311. FreeLibrary(x); \
  312. x = NULL; \
  313. }
  314. RELEASE_LIB(audio_toolbox);
  315. #undef RELEASE_LIB
  316. }
  317. static bool load_lib(void)
  318. {
  319. PWSTR common_path;
  320. if (SHGetKnownFolderPath(FOLDERID_ProgramFilesCommon, 0, NULL,
  321. &common_path) != S_OK) {
  322. CA_LOG(LOG_WARNING, "Could not retrieve common files path");
  323. return false;
  324. }
  325. struct dstr path = {0};
  326. dstr_printf(&path, "%S\\Apple\\Apple Application Support", common_path);
  327. CoTaskMemFree(common_path);
  328. wchar_t *w_path = dstr_to_wcs(&path);
  329. dstr_free(&path);
  330. SetDllDirectory(w_path);
  331. bfree(w_path);
  332. #define LOAD_LIB(x, n) \
  333. x = LoadLibrary(TEXT(n)); \
  334. if (!x) \
  335. CA_LOG(LOG_DEBUG, "Failed loading library '" n "'");
  336. LOAD_LIB(audio_toolbox, "CoreAudioToolbox.dll");
  337. #undef LOAD_LIB
  338. SetDllDirectory(NULL);
  339. if (audio_toolbox)
  340. return true;
  341. release_lib();
  342. return false;
  343. }
  344. static void unload_core_audio(void)
  345. {
  346. AudioConverterNew = NULL;
  347. AudioConverterDispose = NULL;
  348. AudioConverterReset = NULL;
  349. AudioConverterGetProperty = NULL;
  350. AudioConverterGetPropertyInfo = NULL;
  351. AudioConverterSetProperty = NULL;
  352. AudioConverterFillComplexBuffer = NULL;
  353. AudioFormatGetProperty = NULL;
  354. AudioFormatGetPropertyInfo = NULL;
  355. release_lib();
  356. }
  357. #ifdef _MSC_VER
  358. #pragma warning(push)
  359. #pragma warning(disable : 4706)
  360. #endif
  361. static bool load_core_audio(void)
  362. {
  363. if (!load_lib())
  364. return false;
  365. #define LOAD_SYM_FROM_LIB(sym, lib, dll) \
  366. if (!(sym = (sym##_t)GetProcAddress(lib, #sym))) { \
  367. DWORD err = GetLastError(); \
  368. CA_LOG(LOG_ERROR, \
  369. "Couldn't load " #sym " from " dll ": %lu (0x%lx)", \
  370. err, err); \
  371. goto unload_everything; \
  372. }
  373. #define LOAD_SYM(sym) \
  374. LOAD_SYM_FROM_LIB(sym, audio_toolbox, "CoreAudioToolbox.dll")
  375. LOAD_SYM(AudioConverterNew);
  376. LOAD_SYM(AudioConverterDispose);
  377. LOAD_SYM(AudioConverterReset);
  378. LOAD_SYM(AudioConverterGetProperty);
  379. LOAD_SYM(AudioConverterGetPropertyInfo);
  380. LOAD_SYM(AudioConverterSetProperty);
  381. LOAD_SYM(AudioConverterFillComplexBuffer);
  382. LOAD_SYM(AudioFormatGetProperty);
  383. LOAD_SYM(AudioFormatGetPropertyInfo);
  384. #undef LOAD_SYM
  385. return true;
  386. unload_everything:
  387. unload_core_audio();
  388. return false;
  389. }
  390. #ifdef _MSC_VER
  391. #pragma warning(pop)
  392. #endif