Wideband autonomous SDR analysis engine forked from sdr-visual-suite
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

187 Zeilen
4.8KB

  1. #include <cuda_runtime.h>
  2. #include <math.h>
  3. extern "C" __global__ void gpud_freq_shift_kernel(
  4. const float2* __restrict__ in,
  5. float2* __restrict__ out,
  6. int n,
  7. double phase_inc,
  8. double phase_start
  9. ) {
  10. int idx = blockIdx.x * blockDim.x + threadIdx.x;
  11. if (idx >= n) return;
  12. double phase = phase_start + phase_inc * (double)idx;
  13. const double TWO_PI = 6.283185307179586;
  14. phase = phase - rint(phase / TWO_PI) * TWO_PI;
  15. float si, co;
  16. sincosf((float)phase, &si, &co);
  17. float2 v = in[idx];
  18. out[idx].x = v.x * co - v.y * si;
  19. out[idx].y = v.x * si + v.y * co;
  20. }
  21. extern "C" int gpud_launch_freq_shift_cuda(
  22. const float2* in,
  23. float2* out,
  24. int n,
  25. double phase_inc,
  26. double phase_start
  27. ) {
  28. if (n <= 0) return 0;
  29. const int block = 256;
  30. const int grid = (n + block - 1) / block;
  31. gpud_freq_shift_kernel<<<grid, block>>>(in, out, n, phase_inc, phase_start);
  32. return (int)cudaGetLastError();
  33. }
  34. extern "C" __global__ void gpud_fm_discrim_kernel(
  35. const float2* __restrict__ in,
  36. float* __restrict__ out,
  37. int n
  38. ) {
  39. int idx = blockIdx.x * blockDim.x + threadIdx.x;
  40. if (idx >= n - 1) return;
  41. float2 prev = in[idx];
  42. float2 curr = in[idx + 1];
  43. float re = prev.x * curr.x + prev.y * curr.y;
  44. float im = prev.x * curr.y - prev.y * curr.x;
  45. out[idx] = atan2f(im, re);
  46. }
  47. extern "C" int gpud_launch_fm_discrim_cuda(
  48. const float2* in,
  49. float* out,
  50. int n
  51. ) {
  52. if (n <= 1) return 0;
  53. const int block = 256;
  54. const int grid = (n + block - 1) / block;
  55. gpud_fm_discrim_kernel<<<grid, block>>>(in, out, n);
  56. return (int)cudaGetLastError();
  57. }
  58. extern "C" __global__ void gpud_decimate_kernel(
  59. const float2* __restrict__ in,
  60. float2* __restrict__ out,
  61. int n_out,
  62. int factor
  63. ) {
  64. int idx = blockIdx.x * blockDim.x + threadIdx.x;
  65. if (idx >= n_out) return;
  66. out[idx] = in[idx * factor];
  67. }
  68. extern "C" __constant__ float gpud_fir_taps[256];
  69. extern "C" __global__ void gpud_fir_kernel(
  70. const float2* __restrict__ in,
  71. float2* __restrict__ out,
  72. int n,
  73. int num_taps
  74. ) {
  75. int idx = blockIdx.x * blockDim.x + threadIdx.x;
  76. if (idx >= n) return;
  77. float acc_r = 0.0f;
  78. float acc_i = 0.0f;
  79. for (int k = 0; k < num_taps; ++k) {
  80. int src = idx - k;
  81. if (src < 0) break;
  82. float2 v = in[src];
  83. float t = gpud_fir_taps[k];
  84. acc_r += v.x * t;
  85. acc_i += v.y * t;
  86. }
  87. out[idx] = make_float2(acc_r, acc_i);
  88. }
  89. extern "C" int gpud_upload_fir_taps_cuda(const float* taps, int n) {
  90. if (!taps || n <= 0 || n > 256) return -1;
  91. cudaError_t err = cudaMemcpyToSymbol(gpud_fir_taps, taps, (size_t)n * sizeof(float));
  92. return (int)err;
  93. }
  94. extern "C" int gpud_launch_fir_cuda(
  95. const float2* in,
  96. float2* out,
  97. int n,
  98. int num_taps
  99. ) {
  100. if (n <= 0 || num_taps <= 0 || num_taps > 256) return 0;
  101. const int block = 256;
  102. const int grid = (n + block - 1) / block;
  103. gpud_fir_kernel<<<grid, block>>>(in, out, n, num_taps);
  104. return (int)cudaGetLastError();
  105. }
  106. extern "C" int gpud_launch_decimate_cuda(
  107. const float2* in,
  108. float2* out,
  109. int n_out,
  110. int factor
  111. ) {
  112. if (n_out <= 0 || factor <= 0) return 0;
  113. const int block = 256;
  114. const int grid = (n_out + block - 1) / block;
  115. gpud_decimate_kernel<<<grid, block>>>(in, out, n_out, factor);
  116. return (int)cudaGetLastError();
  117. }
  118. extern "C" __global__ void gpud_am_envelope_kernel(
  119. const float2* __restrict__ in,
  120. float* __restrict__ out,
  121. int n
  122. ) {
  123. int idx = blockIdx.x * blockDim.x + threadIdx.x;
  124. if (idx >= n) return;
  125. float2 v = in[idx];
  126. out[idx] = sqrtf(v.x * v.x + v.y * v.y);
  127. }
  128. extern "C" int gpud_launch_am_envelope_cuda(
  129. const float2* in,
  130. float* out,
  131. int n
  132. ) {
  133. if (n <= 0) return 0;
  134. const int block = 256;
  135. const int grid = (n + block - 1) / block;
  136. gpud_am_envelope_kernel<<<grid, block>>>(in, out, n);
  137. return (int)cudaGetLastError();
  138. }
  139. extern "C" __global__ void gpud_ssb_product_kernel(
  140. const float2* __restrict__ in,
  141. float* __restrict__ out,
  142. int n,
  143. double phase_inc,
  144. double phase_start
  145. ) {
  146. int idx = blockIdx.x * blockDim.x + threadIdx.x;
  147. if (idx >= n) return;
  148. double phase = phase_start + phase_inc * (double)idx;
  149. const double TWO_PI = 6.283185307179586;
  150. phase = phase - rint(phase / TWO_PI) * TWO_PI;
  151. float si, co;
  152. sincosf((float)phase, &si, &co);
  153. float2 v = in[idx];
  154. out[idx] = v.x * co - v.y * si;
  155. }
  156. extern "C" int gpud_launch_ssb_product_cuda(
  157. const float2* in,
  158. float* out,
  159. int n,
  160. double phase_inc,
  161. double phase_start
  162. ) {
  163. if (n <= 0) return 0;
  164. const int block = 256;
  165. const int grid = (n + block - 1) / block;
  166. gpud_ssb_product_kernel<<<grid, block>>>(in, out, n, phase_inc, phase_start);
  167. return (int)cudaGetLastError();
  168. }