2121# SOFTWARE.
2222
2323# distutils: language = c++
24- # cython: language_level= 3str
24+ # cython: language_level = 3str
2525# cython: freethreading_compatible = True
2626from python_hackrf import __version__
2727from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
@@ -155,12 +155,13 @@ class py_operacake_ports(IntEnum):
155155@ cython.boundscheck (False )
156156@ cython.wraparound (False )
157157cdef int __rx_callback(chackrf.hackrf_transfer * transfer) noexcept nogil:
158- global global_callbacks
158+
159159 cdef uint8_t* buffer_ptr = transfer.buffer
160160 cdef uint8_t* np_buffer_ptr
161161 cdef int result = - 1
162162
163163 with gil:
164+
164165 np_buffer = np.empty(transfer.buffer_length, dtype = np.int8)
165166 np_buffer_ptr = < uint8_t* > < uintptr_t> np_buffer.ctypes.data
166167
@@ -179,12 +180,12 @@ cdef int __rx_callback(chackrf.hackrf_transfer *transfer) noexcept nogil:
179180@ cython.boundscheck (False )
180181@ cython.wraparound (False )
181182cdef int __tx_callback(chackrf.hackrf_transfer * transfer) noexcept nogil:
182- global global_callbacks
183183 cdef uint8_t* buffer_ptr = transfer.buffer
184184 cdef uint8_t* np_buffer_ptr
185185 cdef int result = - 1
186186
187187 with gil:
188+
188189 np_buffer = np.empty(transfer.buffer_length, dtype = np.int8)
189190 valid_length = c_int(transfer.valid_length)
190191 np_buffer_ptr = < uint8_t* > < uintptr_t> np_buffer.ctypes.data
@@ -207,12 +208,12 @@ cdef int __tx_callback(chackrf.hackrf_transfer *transfer) noexcept nogil:
207208@ cython.boundscheck (False )
208209@ cython.wraparound (False )
209210cdef int __sweep_callback(chackrf.hackrf_transfer * transfer) noexcept nogil:
210- global global_callbacks
211211 cdef uint8_t* buffer_ptr = transfer.buffer
212212 cdef uint8_t* np_buffer_ptr
213213 cdef int result = - 1
214214
215215 with gil:
216+
216217 np_buffer = np.empty(transfer.buffer_length, dtype = np.int8)
217218 np_buffer_ptr = < uint8_t* > < uintptr_t> np_buffer.ctypes.data
218219
@@ -231,11 +232,11 @@ cdef int __sweep_callback(chackrf.hackrf_transfer *transfer) noexcept nogil:
231232@ cython.boundscheck (False )
232233@ cython.wraparound (False )
233234cdef void __tx_complete_callback(chackrf.hackrf_transfer * transfer, int success) noexcept nogil:
234- global global_callbacks
235235 cdef uint8_t* buffer_ptr = transfer.buffer
236236 cdef uint8_t* np_buffer_ptr
237237
238238 with gil:
239+
239240 np_buffer = np.empty(transfer.buffer_length, dtype = np.int8)
240241 np_buffer_ptr = < uint8_t* > < uintptr_t> np_buffer.ctypes.data
241242
@@ -250,10 +251,10 @@ cdef void __tx_complete_callback(chackrf.hackrf_transfer *transfer, int success)
250251
251252
252253cdef void __tx_flush_callback(void * flush_ctx, int success) noexcept nogil:
253- global global_callbacks
254254 cdef size_t device_ptr = < size_t> flush_ctx
255255
256256 with gil:
257+
257258 if global_callbacks[device_ptr][' __tx_flush_callback' ] is not None :
258259 global_callbacks[device_ptr][' __tx_flush_callback' ](global_callbacks[device_ptr][' device' ], success)
259260
@@ -324,13 +325,14 @@ cdef class PyHackrfDevice:
324325 self .device_data = {}
325326
326327 def __dealloc__ (self ):
327- global global_callbacks
328+ cdef int result
328329
329330 if self .__hackrf_device is not NULL :
330331 if < size_t> self .__hackrf_device in global_callbacks.keys():
331332 global_callbacks.pop(< size_t> self .__hackrf_device)
332333
333- result = chackrf.hackrf_close(self .__hackrf_device)
334+ with nogil:
335+ result = chackrf.hackrf_close(self .__hackrf_device)
334336 self .__hackrf_device = NULL
335337
336338 raise_error(' __dealloc__' , result)
@@ -343,8 +345,6 @@ cdef class PyHackrfDevice:
343345 return & self .__hackrf_device
344346
345347 cdef void _setup_device(self ):
346- global global_callbacks
347-
348348 if self .__hackrf_device is not NULL :
349349 self .serialno = self .pyhackrf_serialno_read()
350350
@@ -362,12 +362,14 @@ cdef class PyHackrfDevice:
362362
363363 # ---- device ---- #
364364 def pyhackrf_close (self ) -> None:
365- global global_callbacks
365+ cdef int result
366+
366367 if self.__hackrf_device is not NULL:
367368 if <size_t> self.__hackrf_device in global_callbacks.keys():
368369 global_callbacks.pop(< size_t> self .__hackrf_device)
369370
370- result = chackrf.hackrf_close(self .__hackrf_device)
371+ with nogil:
372+ result = chackrf.hackrf_close(self .__hackrf_device)
371373 self .__hackrf_device = NULL
372374 self .device_data.clear()
373375
@@ -468,11 +470,21 @@ cdef class PyHackrfDevice:
468470 raise_error('pyhackrf_set_baseband_filter_bandwidth()', result )
469471
470472 def pyhackrf_set_freq(self , freq_hz: int ) -> None:
471- result = chackrf.hackrf_set_freq(self .__hackrf_device, < uint64_t> freq_hz)
473+ cdef int result
474+ cdef uint64_t c_freq_hz = < uint64_t> freq_hz
475+
476+ with nogil:
477+ result = chackrf.hackrf_set_freq(self .__hackrf_device, c_freq_hz)
472478 raise_error('pyhackrf_set_freq()', result )
473479
474480 def pyhackrf_set_freq_explicit(self , i_freq_hz: int , lo_freq_hz: int , path: py_rf_path_filter ) -> None:
475- result = chackrf.hackrf_set_freq_explicit(self .__hackrf_device, < uint64_t> i_freq_hz, < uint64_t> lo_freq_hz, path)
481+ cdef int result
482+ cdef chackrf.rf_path_filter c_path = path
483+ cdef uint64_t c_i_freq_hz = < uint64_t> i_freq_hz
484+ cdef uint64_t c_lo_freq_hz = < uint64_t> lo_freq_hz
485+
486+ with nogil:
487+ result = chackrf.hackrf_set_freq_explicit(self .__hackrf_device, c_i_freq_hz, c_lo_freq_hz, c_path)
476488 raise_error('pyhackrf_set_freq_explicit()', result )
477489
478490 def pyhackrf_set_sample_rate_manual(self , freq_hz: int , divider: int ) -> None:
@@ -488,18 +500,27 @@ cdef class PyHackrfDevice:
488500 raise_error('pyhackrf_set_amp_enable()', result )
489501
490502 def pyhackrf_set_lna_gain(self , value: int ) -> None:
491- value = int (max (0 , min (40 , value)) / 8 ) * 8
492- result = chackrf.hackrf_set_lna_gain(self .__hackrf_device, < uint32_t> value)
503+ cdef int result
504+ cdef uint32_t c_value = < uint32_t> int (max (0 , min (40 , value)) / 8 ) * 8
505+
506+ with nogil:
507+ result = chackrf.hackrf_set_lna_gain(self .__hackrf_device, c_value)
493508 raise_error('pyhackrf_set_lna_gain()', result )
494509
495510 def pyhackrf_set_vga_gain(self , value: int ) -> None:
496- value = int (max (0 , min (62 , value)) / 2 ) * 2
497- result = chackrf.hackrf_set_vga_gain(self .__hackrf_device, < uint32_t> value)
511+ cdef int result
512+ cdef uint32_t c_value = < uint32_t> int (max (0 , min (62 , value)) / 2 ) * 2
513+
514+ with nogil:
515+ result = chackrf.hackrf_set_vga_gain(self .__hackrf_device, c_value)
498516 raise_error('pyhackrf_set_vga_gain()', result )
499517
500518 def pyhackrf_set_txvga_gain(self , value: int ) -> None:
501- value = int (max (0 , min (47 , value)))
502- result = chackrf.hackrf_set_txvga_gain(self .__hackrf_device, < uint32_t> value)
519+ cdef int result
520+ cdef uint32_t c_value = < uint32_t> int (max (0 , min (47 , value)))
521+
522+ with nogil:
523+ result = chackrf.hackrf_set_txvga_gain(self .__hackrf_device, c_value)
503524 raise_error('pyhackrf_set_txvga_gain()', result )
504525
505526 def pyhackrf_set_antenna_enable(self , value: bool ) -> None:
@@ -518,7 +539,11 @@ cdef class PyHackrfDevice:
518539
519540 # ---- streaming ---- #
520541 def pyhackrf_is_streaming(self ) -> bool:
521- result = chackrf.hackrf_is_streaming(self .__hackrf_device)
542+ cdef int result
543+
544+ with nogil:
545+ result = chackrf.hackrf_is_streaming(self .__hackrf_device)
546+
522547 if result == chackrf.hackrf_error.HACKRF_TRUE:
523548 return True
524549 elif result in (chackrf.hackrf_error.HACKRF_ERROR_STREAMING_THREAD_ERR , chackrf.hackrf_error.HACKRF_ERROR_STREAMING_STOPPED , chackrf.hackrf_error.HACKRF_ERROR_STREAMING_EXIT_CALLED ):
@@ -557,19 +582,27 @@ cdef class PyHackrfDevice:
557582 raise_error('pyhackrf_start_rx_sweep()', result )
558583
559584 def pyhackrf_start_rx(self ) -> None:
585+ cdef int result
560586 result = chackrf.hackrf_start_rx(self .__hackrf_device, __rx_callback, NULL )
561587 raise_error('pyhackrf_start_rx()', result )
562588
563589 def pyhackrf_stop_rx(self ) -> None:
564- result = chackrf.hackrf_stop_rx(self .__hackrf_device)
590+ cdef int result
591+
592+ with nogil:
593+ result = chackrf.hackrf_stop_rx(self .__hackrf_device)
565594 raise_error('pyhackrf_stop_rx()', result )
566595
567596 def pyhackrf_start_tx(self ) -> None:
597+ cdef int result
568598 result = chackrf.hackrf_start_tx(self .__hackrf_device, __tx_callback, NULL )
569599 raise_error('pyhackrf_start_tx()', result )
570600
571601 def pyhackrf_stop_tx(self ) -> None:
572- result = chackrf.hackrf_stop_tx(self .__hackrf_device)
602+ cdef int result
603+
604+ with nogil:
605+ result = chackrf.hackrf_stop_tx(self .__hackrf_device)
573606 raise_error('pyhackrf_stop_tx()', result )
574607
575608 def pyhackrf_enable_tx_block_complete_callback(self ) -> None:
@@ -644,44 +677,34 @@ cdef class PyHackrfDevice:
644677
645678 # ---- python callbacks setters ---- #
646679 def set_rx_callback(self , rx_callback_function ) -> None:
647- global global_callbacks
648-
649680 if self.__hackrf_device is not NULL:
650681 global_callbacks[<size_t> self.__hackrf_device]['__rx_callback'] = rx_callback_function
651682 return
652683
653684 raise RuntimeError(f'set_rx_callback() failed: Device not initialized!')
654685
655686 def set_tx_callback(self , tx_callback_function ) -> None:
656- global global_callbacks
657-
658687 if self.__hackrf_device is not NULL:
659688 global_callbacks[<size_t> self.__hackrf_device]['__tx_callback'] = tx_callback_function
660689 return
661690
662691 raise RuntimeError(f'set_tx_callback() failed: Device not initialized!')
663692
664693 def set_sweep_callback(self , sweep_callback_function ) -> None:
665- global global_callbacks
666-
667694 if self.__hackrf_device is not NULL:
668695 global_callbacks[<size_t> self.__hackrf_device]['__sweep_callback'] = sweep_callback_function
669696 return
670697
671698 raise RuntimeError(f'set_sweep_callback() failed: Device not initialized!')
672699
673700 def set_tx_complete_callback(self , tx_complete_callback_function ) -> None:
674- global global_callbacks
675-
676701 if self.__hackrf_device is not NULL:
677702 global_callbacks[<size_t> self.__hackrf_device]['__tx_complete_callback'] = tx_complete_callback_function
678703 return
679704
680705 raise RuntimeError(f'set_tx_complete_callback() failed: Device not initialized!')
681706
682707 def set_tx_flush_callback(self , tx_flush_callback_function ) -> None:
683- global global_callbacks
684-
685708 if self.__hackrf_device is not NULL:
686709 global_callbacks[<size_t> self.__hackrf_device]['__tx_flush_callback'] = tx_flush_callback_function
687710 return
0 commit comments