nidaq
This commit is contained in:
parent
1d9bb73ca7
commit
04f51d2afb
112
python/nidaq.py
Normal file
112
python/nidaq.py
Normal file
@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Thu Oct 19 17:11:56 2023
|
||||
https://github.com/ni/nidaqmx-python/issues/162#issuecomment-1083659663
|
||||
@author: sekisushai
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
import nidaqmx as ni
|
||||
from nidaqmx.constants import TaskMode
|
||||
from scipy import signal
|
||||
from nidaqmx.constants import WAIT_INFINITELY
|
||||
|
||||
def query_devices():
|
||||
"""Queries all the device information connected to the local system."""
|
||||
local = ni.system.System.local()
|
||||
for device in local.devices:
|
||||
print(f"Device Name: {device.name}, Product Type: {device.product_type}")
|
||||
print("Input channels:", [chan.name for chan in device.ai_physical_chans])
|
||||
print("Output channels:", [chan.name for chan in device.ao_physical_chans])
|
||||
#%%
|
||||
def sine_sweep(
|
||||
fs=44100, # Sampling frequency
|
||||
dur = 5, # Sweep duration
|
||||
silence_s = 1, # Silence duration before sweep
|
||||
silence_e = 3, # Silence duration after sweep
|
||||
f1 = 100, # Starting frequency
|
||||
f2 = 20000, # Ending frequency
|
||||
amp = 0.8 # Sweep amplitude
|
||||
):
|
||||
N = dur*fs - int(fs*silence_s) - int(fs*silence_e) # Number of samples
|
||||
|
||||
w1 = 2*np.pi*f1/fs # start of sweep in rad/sample
|
||||
w2 = 2*np.pi*f2/fs # end of sweep in rad/sample
|
||||
|
||||
sinsweep = np.zeros(N)
|
||||
t = np.arange(N)/(N-1)
|
||||
lw = np.log(w2/w1)
|
||||
|
||||
sinsweep = amp * np.sin(w1*(N-1)/lw * (np.exp(t*lw)-1))
|
||||
raw_sinsweep = sinsweep.copy()
|
||||
|
||||
# Find the last zero crossing to avoid the need for fadeout
|
||||
flip_sweep = np.flipud(sinsweep)
|
||||
|
||||
err = 1
|
||||
ii = 0
|
||||
|
||||
while err > 0.001:
|
||||
err = np.abs(flip_sweep[ii])
|
||||
ii += 1
|
||||
|
||||
flip_sweep[0:ii] = 0
|
||||
sinsweep = np.flipud(flip_sweep)
|
||||
|
||||
# the convolutional inverse
|
||||
envelope = (w2/w1)**(-t) # Holters2009, Eq.(9)
|
||||
invfilter = np.flipud(raw_sinsweep)*envelope
|
||||
scaling = np.pi*N*(w1/w2-1)/(2*(w2-w1)*np.log(w1/w2))*(w2-w1)/np.pi; # Holters2009, Eq.10
|
||||
invfilter = invfilter/amp**2/scaling
|
||||
|
||||
# fade-in window (actually set to 0). Fade out removed because causes ringing - cropping at zero cross instead
|
||||
taperStart = signal.tukey(N,0)
|
||||
taperWindow = np.ones(N)
|
||||
taperWindow[0:int(N/2)] = taperStart[0:int(N/2)]
|
||||
sinsweep = sinsweep*taperWindow
|
||||
|
||||
# Complete signal with silence at the begining and at the end
|
||||
N_tot = N + int(fs*silence_s) + int(fs*silence_e)
|
||||
zeroStart = np.zeros(fs*silence_s)
|
||||
zeroEnd = np.zeros(fs*silence_e)
|
||||
sinsweep = np.concatenate((zeroStart, sinsweep, zeroEnd), axis=None)
|
||||
return sinsweep
|
||||
|
||||
def playrec(
|
||||
outdata, sr, input_mapping=['cDAQ1Mod2/ai1'],
|
||||
output_mapping=['cDAQ1Mod1/ao0']
|
||||
):
|
||||
nsamples = outdata.shape[0]
|
||||
with ni.Task() as read_task, ni.Task() as write_task:
|
||||
for o in output_mapping:
|
||||
aochan = write_task.ao_channels.add_ao_voltage_chan(o)
|
||||
aochan.ao_max = 3
|
||||
aochan.ao_min = -3
|
||||
read_task.ai_channels.add_ai_voltage_chan('cDAQ1Mod2/ai0')
|
||||
for i in input_mapping:
|
||||
#aichan = read_task.ai_channels.add_ai_microphone_chan(i)
|
||||
aichan = read_task.ai_channels.add_teds_ai_microphone_chan(i)
|
||||
#aichan.ai_min = -10
|
||||
#aichan.ai_max = 10
|
||||
|
||||
for task in (read_task, write_task):
|
||||
task.timing.cfg_samp_clk_timing(rate=sr,
|
||||
samps_per_chan=nsamples)
|
||||
read_task.control(TaskMode.TASK_RESERVE)
|
||||
write_task.triggers.start_trigger.cfg_dig_edge_start_trig(read_task.triggers.start_trigger.term)
|
||||
write_task.write(outdata, auto_start=False)
|
||||
write_task.start()
|
||||
indata = read_task.read(nsamples, timeout=WAIT_INFINITELY)
|
||||
|
||||
return indata
|
||||
|
||||
if __name__ == "__main__":
|
||||
query_devices()
|
||||
|
||||
sr = 44100
|
||||
duration = 8
|
||||
t = np.linspace(0, duration, sr*duration, endpoint=False)
|
||||
sig = sine_sweep(sr,duration)
|
||||
|
||||
indata = playrec(sig, sr)
|
Loading…
Reference in New Issue
Block a user