alhelpers.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #ifndef ALHELPERS_H
  2. #define ALHELPERS_H
  3. #include "AL/al.h"
  4. #include "AL/alc.h"
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. /* Some helper functions to get the name from the format enums. */
  9. const char *FormatName(ALenum format);
  10. /* Easy device init/deinit functions. InitAL returns 0 on success. */
  11. int InitAL(char ***argv, int *argc);
  12. void CloseAL(void);
  13. /* Cross-platform timeget and sleep functions. */
  14. int altime_get(void);
  15. void al_nssleep(unsigned long nsec);
  16. /* C doesn't allow casting between function and non-function pointer types, so
  17. * with C99 we need to use a union to reinterpret the pointer type. Pre-C99
  18. * still needs to use a normal cast and live with the warning (C++ is fine with
  19. * a regular reinterpret_cast).
  20. */
  21. #if __STDC_VERSION__ >= 199901L
  22. #define FUNCTION_CAST(T, ptr) (union{void *p; T f;}){ptr}.f
  23. #elif defined(__cplusplus)
  24. #define FUNCTION_CAST(T, ptr) reinterpret_cast<T>(ptr)
  25. #else
  26. #define FUNCTION_CAST(T, ptr) (T)(ptr)
  27. #endif
  28. #ifdef __cplusplus
  29. } // extern "C"
  30. #include <cstdio>
  31. #include <iostream>
  32. #include <string>
  33. #include <string_view>
  34. #include "alspan.h"
  35. int InitAL(al::span<std::string_view> &args)
  36. {
  37. ALCdevice *device{};
  38. /* Open and initialize a device */
  39. if(args.size() > 1 && args[0] == "-device")
  40. {
  41. device = alcOpenDevice(std::string{args[1]}.c_str());
  42. if(!device)
  43. std::cerr<< "Failed to open \""<<args[1]<<"\", trying default\n";
  44. args = args.subspan(2);
  45. }
  46. if(!device)
  47. device = alcOpenDevice(nullptr);
  48. if(!device)
  49. {
  50. std::fprintf(stderr, "Could not open a device!\n");
  51. return 1;
  52. }
  53. ALCcontext *ctx{alcCreateContext(device, nullptr)};
  54. if(!ctx || alcMakeContextCurrent(ctx) == ALC_FALSE)
  55. {
  56. if(ctx)
  57. alcDestroyContext(ctx);
  58. alcCloseDevice(device);
  59. std::fprintf(stderr, "Could not set a context!\n");
  60. return 1;
  61. }
  62. const ALCchar *name{};
  63. if(alcIsExtensionPresent(device, "ALC_ENUMERATE_ALL_EXT"))
  64. name = alcGetString(device, ALC_ALL_DEVICES_SPECIFIER);
  65. if(!name || alcGetError(device) != AL_NO_ERROR)
  66. name = alcGetString(device, ALC_DEVICE_SPECIFIER);
  67. std::printf("Opened \"%s\"\n", name);
  68. return 0;
  69. }
  70. #endif
  71. #endif /* ALHELPERS_H */