Somewhere inbetween. Everything broken

This commit is contained in:
Anne de Jong 2019-12-08 14:19:10 +01:00
parent 59f82ae14c
commit a39d8300a1
10 changed files with 544 additions and 136 deletions

2
.gitignore vendored
View File

@ -1,5 +1,6 @@
*.a *.a
*.pyc *.pyc
lasp_rtaudio.cxx
dist dist
CMakeFiles CMakeFiles
CMakeCache.txt CMakeCache.txt
@ -23,6 +24,5 @@ LASP.egg-info
lasp_octave_fir.* lasp_octave_fir.*
lasp/ui_* lasp/ui_*
resources_rc.py resources_rc.py
lasp/device/lasp_daqdevice.c
.ropeproject .ropeproject
.spyproject .spyproject

View File

@ -1,5 +1,5 @@
cmake_minimum_required (VERSION 3.0) cmake_minimum_required (VERSION 3.0)
project(beamforming) project(LASP)
# Whether we want to use blas yes or no # Whether we want to use blas yes or no
set(LASP_USE_BLAS TRUE) set(LASP_USE_BLAS TRUE)
@ -39,6 +39,7 @@ set(Python_ADDITIONAL_VERSIONS "3")
if(LASP_DEBUG) if(LASP_DEBUG)
set(TRACERNAME LASPTracer) set(TRACERNAME LASPTracer)
set(LASP_DEBUG_CYTHON=True)
set(CMAKE_BUILD_TYPE Debug) set(CMAKE_BUILD_TYPE Debug)
message("Building debug code") message("Building debug code")
set(CMAKE_BUILD_TYPE Debug) set(CMAKE_BUILD_TYPE Debug)
@ -46,8 +47,6 @@ if(LASP_DEBUG)
add_definitions(-DTRACERNAME=${TRACERNAME}) add_definitions(-DTRACERNAME=${TRACERNAME})
add_definitions(-DDEBUG) add_definitions(-DDEBUG)
add_definitions(-DTRACER=1) add_definitions(-DTRACER=1)
set(CYTHON_VARIABLES "#cython: boundscheck=True")
# This will produce html files # This will produce html files
set(CYTHON_ANNOTATE ON) set(CYTHON_ANNOTATE ON)
# Add the __FILENAME__ macro # Add the __FILENAME__ macro
@ -55,9 +54,9 @@ if(LASP_DEBUG)
else() else()
message("Building LASP for release") message("Building LASP for release")
set(CMAKE_BUILD_TYPE Release) set(CMAKE_BUILD_TYPE Release)
set(LASP_DEBUG_CYTHON=False)
set(CYTHON_ANNOTATE OFF) set(CYTHON_ANNOTATE OFF)
set(CYTHON_NO_DOCSTRINGS ON) set(CYTHON_NO_DOCSTRINGS ON)
set(CYTHON_VARIABLES "#cython: boundscheck=False,wraparound=False,embedsignature=False,emit_code_comments=False")
# Strip unnecessary symbols # Strip unnecessary symbols
# set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--gc-sections") # set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--gc-sections")
# set(CMAKE_MODULE_LINKER_FLAGS "-Wl,--gc-sections") # set(CMAKE_MODULE_LINKER_FLAGS "-Wl,--gc-sections")

View File

@ -1,6 +1,7 @@
configure_file(config.pxi.in config.pxi) configure_file(config.pxi.in config.pxi)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CYTHON_EXECUTABLE "cython3")
include(UseCython) include(UseCython)
find_package(Numpy REQUIRED ) find_package(Numpy REQUIRED )

View File

@ -1,68 +1,7 @@
import numpy as np import numpy as np
cimport numpy as np cimport numpy as cnp
from libcpp cimport bool
DEF LASP_FLOAT = "@LASP_FLOAT@" DEF LASP_FLOAT = "@LASP_FLOAT@"
DEF LASP_DEBUG_CYTHON = "@LASP_DEBUG_CYTHON@"
IF LASP_FLOAT == "double": from libcpp cimport bool
ctypedef double d
ctypedef double complex c
NUMPY_FLOAT_TYPE = np.float64
NUMPY_COMPLEX_TYPE = np.complex128
CYTHON_NUMPY_FLOAT_t = np.NPY_FLOAT64
CYTHON_NUMPY_COMPLEX_t = np.NPY_COMPLEX128
ELSE:
ctypedef float d
ctypedef float complex c
NUMPY_FLOAT_TYPE = np.float32
NUMPY_COMPLEX_TYPE = np.complex64
CYTHON_NUMPY_FLOAT_t = np.NPY_FLOAT32
CYTHON_NUMPY_COMPLEX_t = np.NPY_COMPLEX64
ctypedef size_t us
cdef extern from "lasp_tracer.h":
void setTracerLevel(int)
void TRACE(int,const char*)
void fsTRACE(int)
void feTRACE(int)
void clearScreen()
cdef extern from "lasp_mat.h":
ctypedef struct dmat:
us n_cols
us n_rows
d* _data
bint _foreign_data
ctypedef struct cmat:
pass
ctypedef cmat vc
ctypedef dmat vd
dmat dmat_foreign_data(us n_rows,
us n_cols,
d* data,
bint own_data)
cmat cmat_foreign_data(us n_rows,
us n_cols,
c* data,
bint own_data)
cmat cmat_alloc(us n_rows,us n_cols)
dmat dmat_alloc(us n_rows,us n_cols)
vd vd_foreign(const us size,d* data)
void vd_free(vd*)
void dmat_free(dmat*)
void cmat_free(cmat*)
void cmat_copy(cmat* to,cmat* from_)
cdef extern from "numpy/arrayobject.h":
void PyArray_ENABLEFLAGS(np.ndarray arr, int flags)
cdef extern from "lasp_python.h":
object dmat_to_ndarray(dmat*,bint transfer_ownership)

View File

@ -1,4 +1,13 @@
set_source_files_properties(lasp_daqdevice.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} ${CYTHON_EXTRA_C_FLAGS}") set_source_files_properties(lasp_daqdevice.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} ${CYTHON_EXTRA_C_FLAGS}")
# set_source_files_properties(lasp_portaudio.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} ${CYTHON_EXTRA_C_FLAGS}")
include_directories(/usr/include/rtaudio)
set_source_files_properties(lasp_rtaudio.pyx PROPERTIES CYTHON_IS_CXX TRUE)
set_source_files_properties(lasp_rtaudio.cxx PROPERTIES COMPILE_FLAGS
"${CMAKE_CXX_FLAGS} ${CYTHON_EXTRA_CXX_FLAGS}")
cython_add_module(lasp_daqdevice lasp_daqdevice.pyx) cython_add_module(lasp_daqdevice lasp_daqdevice.pyx)
# cython_add_module(lasp_portaudio lasp_portaudio.pyx) */
cython_add_module(lasp_rtaudio lasp_rtaudio.pyx)
# target_link_libraries(lasp_portaudio portaudio) */
target_link_libraries(lasp_rtaudio rtaudio)
target_link_libraries(lasp_daqdevice asound) target_link_libraries(lasp_daqdevice asound)

View File

@ -9,11 +9,12 @@ Data Acquistiion (DAQ) device descriptors, and the DAQ devices themselves
""" """
from dataclasses import dataclass, field from dataclasses import dataclass, field
from .lasp_daqdevice import query_devices, DeviceInfo
__all__ = ['DAQConfiguration', 'roga_plugndaq', 'umik',
'default_soundcard', 'configs',
'findDAQDevice']
@dataclass
class DAQInputChannel:
channel_enabled: bool
channel_name: str
sensitivity: float
@dataclass @dataclass
class DAQConfiguration: class DAQConfiguration:
@ -21,11 +22,9 @@ class DAQConfiguration:
Initialize a device descriptor Initialize a device descriptor
Args: Args:
name: Name of the device to appear to the user input_device_name: ASCII name with which to open the device when connected
cardname: ALSA name identifier outut_device_name: ASCII name with which to open the device when connected
cardlongnamematch: Long name according to ALSA en_format: index of the format in the list of sample formats
device_name: ASCII name with which to open the device when connected
en_format: index in the list of sample formats
en_input_rate: index of enabled input sampling frequency [Hz] en_input_rate: index of enabled input sampling frequency [Hz]
in the list of frequencies. in the list of frequencies.
en_input_channels: list of channel indices which are used to en_input_channels: list of channel indices which are used to
@ -42,19 +41,13 @@ class DAQConfiguration:
""" """
input_device_name: bytes
name: str output_device_name: bytes
cardname: str en_bit_depth: int
cardlongnamematch: str
device_name: str
en_format: int
en_input_rate: int en_input_rate: int
en_input_channels: list en_input_channels: list
input_sensitivity: list
input_gain_settings: list
en_input_gain_settings: list = field(default_factory=list) en_input_gain_settings: list = field(default_factory=list)
en_output_rate: int = -1 en_output_rate: int = -1
en_output_channels: list = field(default_factory=list)
def match(self, device): def match(self, device):
""" """
@ -83,50 +76,12 @@ class DAQConfiguration:
return match return match
@staticmethod
roga_plugndaq = DAQConfiguration(name='Roga-instruments Plug.n.DAQ USB', def emptyFromDeviceAndSettings(device):
cardname='USB Audio CODEC', return DAQConfiguration(
cardlongnamematch='Burr-Brown from TI USB' name = 'UNKNOWN'
' Audio CODEC', input_device_name =
device_name='iec958:CARD=CODEC,DEV=0',
en_format=0,
en_input_rate=2,
en_input_channels=[0],
input_sensitivity=[46.92e-3, 46.92e-3],
input_gain_settings=[-20, 0, 20],
en_input_gain_settings=[1, 1],
en_output_rate=1,
en_output_channels=[False, False]
)
umik = DAQConfiguration(name='UMIK-1',
cardname='Umik-1 Gain: 18dB',
cardlongnamematch='miniDSP Umik-1 Gain: 18dB',
device_name='iec958:CARD=U18dB,DEV=0',
en_format=0,
en_input_rate=0,
en_input_channels=[0],
input_sensitivity=[1., 1.],
input_gain_settings=[0., 0.],
en_input_gain_settings=[0, 0],
en_output_rate=0,
en_output_channels=[True, True]
)
default_soundcard = DAQConfiguration(name="Default device",
cardname=None,
cardlongnamematch=None,
device_name='default',
en_format=0,
en_input_rate=2,
en_input_channels=[0],
input_sensitivity=[1.0, 1.0],
input_gain_settings=[0],
en_input_gain_settings=[0, 0],
en_output_rate=1,
en_output_channels=[]
)
configs = (roga_plugndaq, default_soundcard)
def findDAQDevice(config: DAQConfiguration) -> DeviceInfo: def findDAQDevice(config: DAQConfiguration) -> DeviceInfo:
""" """

View File

@ -0,0 +1,389 @@
import sys
include "config.pxi"
cimport cython
from libcpp.string cimport string
from libcpp.vector cimport vector
from libc.string cimport memcpy
cdef extern from "RtAudio.h" nogil:
ctypedef unsigned long RtAudioStreamStatus
RtAudioStreamStatus RTAUDIO_INPUT_OVERFLOW
RtAudioStreamStatus RTAUDIO_OUTPUT_UNDERFLOW
cdef cppclass RtAudioError:
ctypedef enum Type:
WARNING
DEBUG_WARNING
UNSPECIFIED
NO_DEVICES_FOUND
INVALID_DEVICE
MEMORY_ERROR
INVALID_PARAMETER
INVALID_USE
DRIVER_ERROR
SYSTEM_ERROR
THREAD_ERROR
ctypedef unsigned long RtAudioStreamFlags
RtAudioStreamFlags RT_AUDIO_NONINTERLEAVED
RtAudioStreamFlags RTAUDIO_MINIMIZE_LATENCY
RtAudioStreamFlags RTAUDIO_HOG_DEVICE
RtAudioStreamFlags RTAUDIO_ALSA_USE_DEFAULT
RtAudioStreamFlags RTAUDIO_JACK_DONT_CONNECT
ctypedef unsigned long RtAudioFormat
RtAudioFormat RTAUDIO_SINT8
RtAudioFormat RTAUDIO_SINT16
RtAudioFormat RTAUDIO_SINT24
RtAudioFormat RTAUDIO_SINT32
RtAudioFormat RTAUDIO_FLOAT32
RtAudioFormat RTAUDIO_FLOAT64
ctypedef int (*RtAudioCallback)(void* outputBuffer,
void* inputBuffer,
unsigned int nFrames,
double streamTime,
RtAudioStreamStatus status,
void* userData)
ctypedef void (*RtAudioErrorCallback)(RtAudioError.Type _type,
const string& errortxt)
cdef cppclass cppRtAudio "RtAudio":
cppclass DeviceInfo:
bool probed
string name
unsigned int outputChannels
unsigned int inputChannels
unsigned int duplexChannels
bool isDefaultOutput
bool isDefaultInput
vector[unsigned int] sampleRates
unsigned int preferredSampleRate
RtAudioFormat nativeFormats
cppclass StreamOptions:
RtAudioStreamFlags flags
unsigned int numberOfBuffers
string streamName
int priority
cppclass StreamParameters:
unsigned int deviceId
unsigned int nChannels
unsigned int firstChannel
RtAudio() except +
# ~RtAudio() Destructors should not be listed
unsigned int getDeviceCount()
DeviceInfo getDeviceInfo(unsigned int device)
unsigned int getDefaultOutputDevice()
unsigned int getDefaultInputDevice()
void openStream(StreamParameters* outputParameters,
StreamParameters* intputParameters,
RtAudioFormat _format,
unsigned int sampleRate,
unsigned int* bufferFrames,
RtAudioCallback callback,
void* userData,
void* StreamOptions,
RtAudioErrorCallback) except +
void closeStream()
void startStream() except +
void stopStream() except +
void abortStream() except +
bool isStreamOpen()
bool isStreamRunning()
double getStreamTime()
void setStreamTime(double) except +
long getStreamLatency()
unsigned int getStreamSampleRate()
void showWarnings(bool value)
cdef class SampleFormat:
cdef:
RtAudioFormat _format
string _name
public:
# The size in bytes of a single audio sample, for the current
# format
unsigned int sampleSize
def __cinit__(self, RtAudioFormat format_):
self._format = format_
if format_ == RTAUDIO_SINT8:
self._name = b'8-bit integers'
self.sampleSize = 1
elif format_ == RTAUDIO_SINT16:
self._name = b'16-bit integers'
self.sampleSize = 2
elif format_ == RTAUDIO_SINT24:
self._name = b'24-bit integers'
self.sampleSize = 3
elif format_ == RTAUDIO_SINT32:
self._name = b'32-bit integers'
self.sampleSize = 4
elif format_ == RTAUDIO_FLOAT32:
self._name = b'32-bit floats'
self.sampleSize = 4
elif format_ == RTAUDIO_FLOAT64:
self._name = b'64-bit floats'
self.sampleSize = 8
else:
raise ValueError('Invalid RtAudioFormat code')
def __repr__(self):
return self._name.decode('utf-8')
def __str__(self):
return self.__repr__()
# Pre-define format and expose to Python
Format_SINT8 = SampleFormat(RTAUDIO_SINT8)
Format_SINT16 = SampleFormat(RTAUDIO_SINT16)
Format_SINT24 = SampleFormat(RTAUDIO_SINT24)
Format_SINT32 = SampleFormat(RTAUDIO_SINT32)
Format_FLOAT32 = SampleFormat(RTAUDIO_FLOAT32)
Format_FLOAT64 = SampleFormat(RTAUDIO_FLOAT64)
cdef class _Stream:
cdef:
object pyCallback
RtAudioFormat format
cppRtAudio.StreamParameters inputParams
cppRtAudio.StreamParameters outputParams
# These boolean values tell us whether the structs above here are
# initialized and contain valid data
bool hasInput
bool hasOutput
unsigned int bufferFrames
# It took me quite a long time to fully understand Cython's idiosyncrasies
# concerning C(++) callbacks, the GIL and passing Python objects as pointers
# into C(++) functions. But finally, here it is!
cdef object fromBufferToNPYNoCopy(buffer_format_type,
void* buf,
size_t nchannels,
size_t nframes):
cdef cnp.npy_intp[2] dims = [nchannels, nframes];
array = cnp.PyArray_SimpleNewFromData(2, dims, buffer_format_type,
buf)
return array
cdef void fromNPYToBuffer(cnp.ndarray arr,
void* buf):
"""
Copy a Python numpy array over to a buffer
No checks, just memcpy! Careful!
"""
memcpy(buf, arr.data, arr.size*arr.itemsize)
cdef int audioCallback(void* outputBuffer,
void* inputBuffer,
unsigned int nFrames,
double streamTime,
RtAudioStreamStatus status,
void* userData) nogil:
"""
Calls the Python callback function and converts data
"""
cdef int rval = 0
with gil:
if status == RTAUDIO_INPUT_OVERFLOW:
print('Input overflow.')
return 0
if status == RTAUDIO_OUTPUT_UNDERFLOW:
print('Output underflow.')
return 0
stream = <_Stream>(userData)
# Obtain stream information
npy_input = None
if stream.hasInput:
assert inputBuffer != NULL
# cdef
try:
npy_output, rval = stream.pyCallback(npy_input,
nFrames,
streamTime)
except Exception as e:
print('Exception in Python callback: ', str(e))
return 1
if stream.hasOutput:
if npy_output is None:
print('No output buffer given!')
return 1
IF LASP_DEBUG_CYTHON:
try:
assert outputBuffer != NULL, "Bug: RtAudio does not give output buffer!"
assert npy_output.shape[0] == stream.outputParams.nChannels, "Bug: channel mismatch in output buffer!"
assert npy_output.shape[1] == nFrames, "Bug: frame mismatch in output buffer!"
assert npy_output.itemsize == stream._format.sampleSize, "Bug: invalid sample type in output buffer!"
except AssertionError as e:
print(e)
fromNPYToBuffer(npy_output, outputBuffer)
return rval
cdef void errorCallback(RtAudioError.Type _type,const string& errortxt) nogil:
pass
cdef class RtAudio:
cdef:
cppRtAudio _rtaudio
_Stream _stream
def __cinit__(self):
self._stream = None
def __dealloc__(self):
if self._stream is not None:
print('Force closing stream')
self._rtaudio.closeStream()
cpdef unsigned int getDeviceCount(self):
return self._rtaudio.getDeviceCount()
cpdef unsigned int getDefaultOutputDevice(self):
return self._rtaudio.getDefaultOutputDevice()
cpdef unsigned int getDefaultInputDevice(self):
return self._rtaudio.getDefaultInputDevice()
def getDeviceInfo(self, unsigned int device):
"""
Return device information of the current device
"""
cdef cppRtAudio.DeviceInfo devinfo = self._rtaudio.getDeviceInfo(device)
pydevinfo = {}
pydevinfo['index'] = device
pydevinfo['probed'] = devinfo.probed
pydevinfo['name'] = devinfo.name.decode('utf-8')
pydevinfo['outputchannels'] = devinfo.outputChannels
pydevinfo['inputchannels'] = devinfo.inputChannels
pydevinfo['duplexchannels'] = devinfo.duplexChannels
pydevinfo['isdefaultoutput'] = devinfo.isDefaultOutput
pydevinfo['isdefaultinpput'] = devinfo.isDefaultInput
pydevinfo['samplerates'] = devinfo.sampleRates
pydevinfo['prefsamprate'] = devinfo.preferredSampleRate
# Manually add these
nf = devinfo.nativeFormats
sampleformats = []
for format_ in [ RTAUDIO_SINT8, RTAUDIO_SINT16, RTAUDIO_SINT24,
RTAUDIO_SINT32, RTAUDIO_FLOAT32, RTAUDIO_FLOAT64]:
if nf & format_:
sampleformats.append(SampleFormat(format_))
pydevinfo['sampleformats'] = sampleformats
return pydevinfo
def openStream(self,object outputParams,
object inputParams,
SampleFormat format,
unsigned int sampleRate,
unsigned int bufferFrames,
object pyCallback,
object options = None,
object pyErrorCallback = None):
"""
Opening a stream with specified parameters
Args:
outputParams: dictionary of stream outputParameters, set to None
if no outputPararms are specified
inputParams: dictionary of stream inputParameters, set to None
if no inputPararms are specified
sampleRate: desired sample rate.
bufferFrames: the amount of frames in a callback buffer
callback: callback to call. Note: this callback is called on a
different thread!
options: A dictionary of optional additional stream options
errorCallback: client-defined function that will be invoked when an
error has occured.
Returns: None
"""
if self._stream is not None:
raise RuntimeError('Stream is already opened.')
cdef cppRtAudio.StreamParameters *rtOutputParams_ptr = NULL
cdef cppRtAudio.StreamParameters *rtInputParams_ptr = NULL
cdef cppRtAudio.StreamOptions streamoptions
streamoptions.flags = RTAUDIO_HOG_DEVICE
streamoptions.numberOfBuffers = 4
self._stream = _Stream()
self._stream.pyCallback = pyCallback
if outputParams is not None:
rtOutputParams_ptr = &self._stream.outputParams
rtOutputParams_ptr.deviceId = outputParams['deviceid']
rtOutputParams_ptr.nChannels = outputParams['nchannels']
rtOutputParams_ptr.firstChannel = outputParams['firstchannel']
self._stream.hasOutput = True
if inputParams is not None:
rtOutputParams_ptr = &self._stream.inputParams
rtInputParams_ptr.deviceId = inputParams['deviceid']
rtInputParams_ptr.nChannels = inputParams['nchannels']
rtInputParams_ptr.firstChannel = inputParams['firstchannel']
self._stream.hasInput = True
try:
self._stream.bufferFrames = bufferFrames
self._rtaudio.openStream(rtOutputParams_ptr,
rtInputParams_ptr,
format._format,
sampleRate,
&self._stream.bufferFrames,
audioCallback,
<void*> self._stream,
&streamoptions, # Stream options
errorCallback # Error callback
)
except Exception as e:
print('Exception occured in stream opening: ', str(e))
self._stream = None
def startStream(self):
self._rtaudio.startStream()
def stopStream(self):
if not self._stream:
raise RuntimeError('Stream is not opened')
self._rtaudio.stopStream()
def closeStream(self):
if not self._stream:
raise RuntimeError('Stream is not opened')
# Closing stream
self._rtaudio.closeStream()
self._stream = None
def abortStream(self):
if not self._stream:
raise RuntimeError('Stream is not opened')
self._rtaudio.abortStream()
def isStreamOpen(self):
return self._rtaudio.isStreamOpen()
def isStreamRunning(self):
return self._rtaudio.isStreamRunning()
def getStreamTime(self):
return self._rtaudio.getStreamTime()
def setStreamTime(self, double time):
return self._rtaudio.setStreamTime(time)

View File

@ -2,14 +2,36 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import numpy as np import numpy as np
from .wrappers import Window as wWindow from .wrappers import Window as wWindow
import appdirs, os, shelve
""" """
Common definitions used throughout the code. Common definitions used throughout the code.
""" """
__all__ = ['P_REF', 'FreqWeighting', 'TimeWeighting', 'getTime', 'calfile', __all__ = ['P_REF', 'FreqWeighting', 'TimeWeighting', 'getTime',
'getFreq', 'getFreq', 'lasp_shelve'
'W_REF', 'U_REF', 'I_REF'] 'W_REF', 'U_REF', 'I_REF']
lasp_appdir = appdirs.user_data_dir('Lasp', 'ASCEE')
if not os.path.exists(lasp_appdir):
try:
os.mkdir(lasp_appdir)
except:
print('Fatal error: could not create application directory')
exit(1)
class lasp_shelve:
def __enter__(self):
self.shelve = shelve.open(os.path.join(lasp_appdir, 'config.shelve'))
return self.shelve
def __exit__(self, type, value, traceback):
self.shelve.close()
# Reference sound pressure level # Reference sound pressure level
P_REF = 2e-5 P_REF = 2e-5
@ -19,9 +41,6 @@ I_REF = 1e-12 # 1 picoWatt/ m^2
# Reference velocity for sound velocity level # Reference velocity for sound velocity level
U_REF = 5e-8 U_REF = 5e-8
# Todo: fix This
calfile = None
class Window: class Window:
hann = (wWindow.hann, 'Hann') hann = (wWindow.hann, 'Hann')

View File

@ -2,6 +2,68 @@
This file contains the Cython wrapper functions to C implementations. This file contains the Cython wrapper functions to C implementations.
""" """
include "config.pxi" include "config.pxi"
IF LASP_FLOAT == "double":
ctypedef double d
ctypedef double complex c
NUMPY_FLOAT_TYPE = np.float64
NUMPY_COMPLEX_TYPE = np.complex128
CYTHON_NUMPY_FLOAT_t = cnp.NPY_FLOAT64
CYTHON_NUMPY_COMPLEX_t = cnp.NPY_COMPLEX128
ELSE:
ctypedef float d
ctypedef float complex c
NUMPY_FLOAT_TYPE = np.float32
NUMPY_COMPLEX_TYPE = np.complex64
CYTHON_NUMPY_FLOAT_t = cnp.NPY_FLOAT32
CYTHON_NUMPY_COMPLEX_t = cnp.NPY_COMPLEX64
ctypedef size_t us
cdef extern from "lasp_tracer.h":
void setTracerLevel(int)
void TRACE(int,const char*)
void fsTRACE(int)
void feTRACE(int)
void clearScreen()
cdef extern from "lasp_mat.h":
ctypedef struct dmat:
us n_cols
us n_rows
d* _data
bint _foreign_data
ctypedef struct cmat:
pass
ctypedef cmat vc
ctypedef dmat vd
dmat dmat_foreign_data(us n_rows,
us n_cols,
d* data,
bint own_data)
cmat cmat_foreign_data(us n_rows,
us n_cols,
c* data,
bint own_data)
cmat cmat_alloc(us n_rows,us n_cols)
dmat dmat_alloc(us n_rows,us n_cols)
vd vd_foreign(const us size,d* data)
void vd_free(vd*)
void dmat_free(dmat*)
void cmat_free(cmat*)
void cmat_copy(cmat* to,cmat* from_)
cdef extern from "numpy/arrayobject.h":
void PyArray_ENABLEFLAGS(cnp.ndarray arr, int flags)
cdef extern from "lasp_python.h":
object dmat_to_ndarray(dmat*,bint transfer_ownership)
__all__ = ['AvPowerSpectra'] __all__ = ['AvPowerSpectra']

35
test/test_rtaudio.py Normal file
View File

@ -0,0 +1,35 @@
#!/usr/bin/python3
import numpy as np
from lasp_rtaudio import RtAudio, SampleFormat, Format_SINT32, Format_FLOAT64
import time
nframes = 0
samplerate = 48000
omg = 2*np.pi*1000
def mycallback(input_, nframes, streamtime):
t = np.linspace(streamtime, streamtime + nframes/samplerate,
nframes)[np.newaxis,:]
outp = 0.1*np.sin(omg*t)
return outp, 0
if __name__ == '__main__':
pa = RtAudio()
count = pa.getDeviceCount()
# dev = pa.getDeviceInfo(0)
for i in range(count):
dev = pa.getDeviceInfo(i)
print(dev)
outputparams = {'deviceid': 0, 'nchannels': 1, 'firstchannel': 0}
pa.openStream(outputparams, None , Format_FLOAT64,samplerate, 512, mycallback)
pa.startStream()
input()
pa.stopStream()
pa.closeStream()