windows-imports.h 18 KB

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