diff --git a/lasp/device/lasp_cppuldaq.cpp b/lasp/device/lasp_cppuldaq.cpp index 35a4a91..d94ba8c 100644 --- a/lasp/device/lasp_cppuldaq.cpp +++ b/lasp/device/lasp_cppuldaq.cpp @@ -350,7 +350,7 @@ void threadfcn(DT9837A* td) { if(outxstat.currentIndex < buffer_mid_idx_out) { topoutenqueued = false; if(!botoutenqueued) { - cerr << "Copying output buffer to bottom" << endl; + /* cerr << "Copying output buffer to bottom" << endl; */ double* bufcpy; if(!outqueue->empty()) { bufcpy = outqueue->dequeue(); @@ -374,7 +374,7 @@ void threadfcn(DT9837A* td) { botoutenqueued = false; if(!topoutenqueued) { topoutenqueued = true; - cerr << "Copying output buffer to top" << endl; + /* cerr << "Copying output buffer to top" << endl; */ double* bufcpy; if(!outqueue->empty()) { bufcpy = outqueue->dequeue(); @@ -407,7 +407,7 @@ void threadfcn(DT9837A* td) { if(inxstat.currentIndex < buffer_mid_idx_in) { topinenqueued = false; if(!botinenqueued) { - cerr << "Copying in buffer bot" << endl; + /* cerr << "Copying in buffer bot" << endl; */ double* bufcpy = static_cast(malloc(sizeof(double)*samplesPerBlock*neninchannels)); us monitoroffset = monitorOutput ? 1: 0; assert(neninchannels > 0); @@ -448,7 +448,7 @@ void threadfcn(DT9837A* td) { } } - cerr << "Copying in buffer top" << endl; + /* cerr << "Copying in buffer top" << endl; */ inqueue->enqueue(bufcpy); topinenqueued = true; } diff --git a/lasp/device/lasp_uldaq.pyx b/lasp/device/lasp_uldaq.pyx index eb6b5c1..74532e5 100644 --- a/lasp/device/lasp_uldaq.pyx +++ b/lasp/device/lasp_uldaq.pyx @@ -11,7 +11,7 @@ DEF UL_ERR_MSG_LEN = 512 ctypedef unsigned us -cdef extern from "lasp_cppdaq.h": +cdef extern from "lasp_cppdaq.h" nogil: cdef cppclass Daq: void start(SafeQueue[double*] *inQueue, SafeQueue[double*] *outQueue) @@ -92,6 +92,7 @@ cdef void audioCallbackPythonThreadFunction(void* voidsd) nogil: if sd.inQueue: if not sd.outQueue: + # Waiting indefinitely on the queue... inbuffer = sd.inQueue.dequeue() if inbuffer == NULL: printf('Stopping thread...\n') @@ -99,13 +100,14 @@ cdef void audioCallbackPythonThreadFunction(void* voidsd) nogil: else: if not sd.inQueue.empty(): inbuffer = sd.inQueue.dequeue() + if inbuffer == NULL: + printf('Stopping thread...\n') + return else: inbuffer = NULL with gil: - # Obtain stream information - npy_input = None npy_output = None if sd.inQueue and inbuffer: try: @@ -117,12 +119,22 @@ cdef void audioCallbackPythonThreadFunction(void* voidsd) nogil: True, # Do transfer ownership True) # F-contiguous is True: data is Fortran-cont. + rval = callback(npy_input, + npy_output, + nFramesPerBlock, + ) + except Exception as e: print('exception in cython callback for audio input: ', str(e)) return + npy_input = None if sd.outQueue: # fprintf(stderr, 'Copying output buffer to Numpy...\n') + rval = callback(npy_input, + npy_output, + nFramesPerBlock, + ) try: npy_output = data_to_ndarray( outbuffer, @@ -136,14 +148,6 @@ cdef void audioCallbackPythonThreadFunction(void* voidsd) nogil: print('exception in Cython callback for audio output: ', str(e)) return - try: - rval = callback(npy_input, - npy_output, - nFramesPerBlock, - ) - except Exception as e: - print('Exception in Cython callback: ', str(e)) - return if sd.outQueue: sd.outQueue.enqueue( outbuffer) @@ -151,7 +155,7 @@ cdef void audioCallbackPythonThreadFunction(void* voidsd) nogil: while sd.outQueue.size() > 10 and not sd.stopThread.load(): # printf('Sleeping...\n') # No input queue to wait on, so we relax a bit here. - CPPsleep_ms(1); + CPPsleep_us(10); # Outputbuffer is free'ed by the audiothread, so should not be touched # here. @@ -160,6 +164,8 @@ cdef void audioCallbackPythonThreadFunction(void* voidsd) nogil: # Inputbuffer memory is owned by Numpy, so should not be free'ed inbuffer = NULL + fprintf(stderr, 'Exiting python thread...\n') + cdef class UlDaq: cdef: PyStreamData *sd @@ -174,6 +180,15 @@ cdef class UlDaq: self.daq_device = NULL self.sd = NULL + def __dealloc__(self): + fprintf(stderr, "UlDaq.__dealloc__\n") + if self.sd is not NULL: + fprintf(stderr, "UlDaq.__dealloc__, stopping stream.\n") + self.stop() + + def isRunning(self): + return self.sd is not NULL + @cython.nonecheck(True) def start(self, avstream): """ @@ -258,7 +273,7 @@ cdef class UlDaq: # Create channel maps for in channels, set in stream # parameters - inch_enabled = 4*False + inch_enabled = 4*[False] if in_stream: inch_enabled = [True if ch.channel_enabled else False for ch in daqconfig.getInputChannels()] @@ -266,7 +281,7 @@ cdef class UlDaq: self.sd.inQueue = new SafeQueue[double*]() # Create channel maps for output channels - outch_enabled = 4*False + outch_enabled = 1*[False] if out_stream: print('Stream is output stream') outch_enabled = [True if ch.channel_enabled else False for ch in @@ -279,7 +294,7 @@ cdef class UlDaq: daqconfig.nFramesPerBlock, inch_enabled, outch_enabled, - daqconfig.samplerate, + samplerate, monitorOutput, device.index) else: diff --git a/lasp/device/test_uldaq b/lasp/device/test_uldaq new file mode 100755 index 0000000..b652c89 Binary files /dev/null and b/lasp/device/test_uldaq differ