common.h (4347B)
1 /* 2 * Copyright © 2013 Sebastien Alaiwan 3 * 4 * This program is made available under an ISC-style license. See the 5 * accompanying file LICENSE for details. 6 */ 7 #if !defined(TEST_COMMON) 8 #define TEST_COMMON 9 10 #if defined(_WIN32) 11 #ifndef WIN32_LEAN_AND_MEAN 12 #define WIN32_LEAN_AND_MEAN 13 #endif 14 #include <objbase.h> 15 #include <windows.h> 16 #else 17 #include <unistd.h> 18 #endif 19 20 #include "cubeb/cubeb.h" 21 #include "cubeb_mixer.h" 22 #include "gtest/gtest.h" 23 #include <cstdarg> 24 #include <cstdio> 25 #include <cstring> 26 27 template <typename T, size_t N> 28 constexpr size_t 29 ARRAY_LENGTH(T (&)[N]) 30 { 31 return N; 32 } 33 34 inline void 35 delay(unsigned int ms) 36 { 37 #if defined(_WIN32) 38 Sleep(ms); 39 #else 40 sleep(ms / 1000); 41 usleep(ms % 1000 * 1000); 42 #endif 43 } 44 45 #if !defined(M_PI) 46 #define M_PI 3.14159265358979323846 47 #endif 48 49 typedef struct { 50 char const * name; 51 unsigned int const channels; 52 uint32_t const layout; 53 } layout_info; 54 55 struct backend_caps { 56 const char * id; 57 const int input_capabilities; 58 }; 59 60 // This static table allows knowing if a backend has audio input capabilities. 61 // We don't rely on opening a stream and checking if it works, because this 62 // would make the test skip the tests that make use of audio input, if a 63 // particular backend has a bug that causes a failure during audio input stream 64 // creation 65 static backend_caps backend_capabilities[] = { 66 {"sun", 1}, {"wasapi", 1}, {"kai", 1}, {"audiounit", 1}, 67 {"audiotrack", 0}, {"opensl", 1}, {"aaudio", 1}, {"jack", 1}, 68 {"pulse", 1}, {"sndio", 1}, {"oss", 1}, {"winmm", 0}, 69 {"alsa", 1}, 70 }; 71 72 inline int 73 can_run_audio_input_test(cubeb * ctx) 74 { 75 cubeb_device_collection devices; 76 int input_device_available = 0; 77 int r; 78 /* Bail out early if the host does not have input devices. */ 79 r = cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_INPUT, &devices); 80 if (r != CUBEB_OK) { 81 fprintf(stderr, "error enumerating devices."); 82 return 0; 83 } 84 85 if (devices.count == 0) { 86 fprintf(stderr, "no input device available, skipping test.\n"); 87 cubeb_device_collection_destroy(ctx, &devices); 88 return 0; 89 } 90 91 for (uint32_t i = 0; i < devices.count; i++) { 92 input_device_available |= 93 (devices.device[i].state == CUBEB_DEVICE_STATE_ENABLED); 94 } 95 96 if (!input_device_available) { 97 fprintf(stderr, "there are input devices, but they are not " 98 "available, skipping\n"); 99 } 100 101 cubeb_device_collection_destroy(ctx, &devices); 102 103 int backend_has_input_capabilities; 104 const char * backend_id = cubeb_get_backend_id(ctx); 105 for (uint32_t i = 0; i < sizeof(backend_capabilities) / sizeof(backend_caps); 106 i++) { 107 if (strcmp(backend_capabilities[i].id, backend_id) == 0) { 108 backend_has_input_capabilities = 109 backend_capabilities[i].input_capabilities; 110 } 111 } 112 113 return !!input_device_available && !!backend_has_input_capabilities; 114 } 115 116 inline void 117 print_log(const char * msg, ...) 118 { 119 va_list args; 120 va_start(args, msg); 121 vprintf(msg, args); 122 printf("\n"); 123 va_end(args); 124 } 125 126 /** Initialize cubeb with backend override. 127 * Create call cubeb_init passing value for CUBEB_BACKEND env var as 128 * override. */ 129 inline int 130 common_init(cubeb ** ctx, char const * ctx_name) 131 { 132 #ifdef ENABLE_NORMAL_LOG 133 if (cubeb_set_log_callback(CUBEB_LOG_NORMAL, print_log) != CUBEB_OK) { 134 fprintf(stderr, "Set normal log callback failed\n"); 135 } 136 #endif 137 138 #ifdef ENABLE_VERBOSE_LOG 139 if (cubeb_set_log_callback(CUBEB_LOG_VERBOSE, print_log) != CUBEB_OK) { 140 fprintf(stderr, "Set verbose log callback failed\n"); 141 } 142 #endif 143 144 int r; 145 char const * backend; 146 char const * ctx_backend; 147 148 backend = getenv("CUBEB_BACKEND"); 149 r = cubeb_init(ctx, ctx_name, backend); 150 if (r == CUBEB_OK && backend) { 151 ctx_backend = cubeb_get_backend_id(*ctx); 152 if (strcmp(backend, ctx_backend) != 0) { 153 fprintf(stderr, "Requested backend `%s', got `%s'\n", backend, 154 ctx_backend); 155 } 156 } 157 158 return r; 159 } 160 161 #if defined(_WIN32) 162 class TestEnvironment : public ::testing::Environment { 163 public: 164 void SetUp() override { hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); } 165 166 void TearDown() override 167 { 168 if (SUCCEEDED(hr)) { 169 CoUninitialize(); 170 } 171 } 172 173 private: 174 HRESULT hr; 175 }; 176 177 ::testing::Environment * const foo_env = 178 ::testing::AddGlobalTestEnvironment(new TestEnvironment); 179 #endif 180 181 #endif /* TEST_COMMON */