mercoledì 14 gennaio 2026

Microfoni Kinect1

Ho trovato quasi per caso su Internet che il Kinect 1 ha un array di 4 microfoni che permettono di determinare la direzione del suono (ed essendo tutto integrato non ha problemi di jitter) 

Bus 001 Device 016: ID 045e:02b0 Microsoft Corp. Xbox NUI Motor
Bus 001 Device 018: ID 045e:02bb Microsoft Corp. Kinect Audio
Bus 001 Device 019: ID 045e:02ae Microsoft Corp. Xbox NUI Camera
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

L'array di 4 microfoni e' indicato da 0 (lato destro) a 3 (lato sinistro) con una distanza tra 0 e 3 di 22.6 cm. I microfoni 0,1,2 sono molto ravvicinati tra di loro, solo il 3 e' distanziato alla sinistra


 

Una delle limitazione di kinect e' che il campionamento massimo e' di 16k il che limita la precisione a 2.14 cm ed 24 bit (anche se sono trasmessi come 32 bit)

arecord -l

 card 1: Audio [Kinect USB Audio], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0


arecord -D hw:1,0 -c 4 -r 16000 -f S32_LE -t raw kinect_array.raw 

ffmpeg -f s32le -ar 16000 -ac 4 -i kinect_array.raw kinect_output.wav 

 

import numpy as np
import subprocess
import math
from scipy.signal import correlate

# --- CONFIGURAZIONE ---
CHANNELS = 4
RATE = 16000
CHUNK_SIZE = 1024 * 4 # Dimensione del blocco da analizzare (circa 0.25 secondi)
v = 343 # Velocità del suono m/s
d = 0.226 # Distanza Mic 0 - Mic 3 (metri)

# Comando per avviare arecord e inviare i dati RAW alla stdout
cmd = [
'arecord', '-D', 'hw:1,0', '-c', str(CHANNELS), '-r', str(RATE),
'-f', 'S32_LE', '-t', 'raw', '-q'
]

# Avvio del processo
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)

print("Ascolto in corso... Muoviti davanti al Kinect o schiocca le dita!")
print("Premi Ctrl+C per fermare.\n")

try:
while True:
# Leggi un blocco di dati (4 canali * 4 byte per campione * CHUNK_SIZE)
raw_bytes = proc.stdout.read(CHUNK_SIZE * CHANNELS * 4)
if not raw_bytes:
break

# Converti byte in array numpy
data = np.frombuffer(raw_bytes, dtype=np.int32).reshape(-1, CHANNELS)

# Prendi Mic 0 e Mic 3
mic_0 = data[:, 0].astype(np.float32)
mic_3 = data[:, 3].astype(np.float32)

# Calcola correlazione
corr = correlate(mic_0, mic_3, mode='full')
lag = np.argmax(corr) - (len(mic_0) - 1)
# Calcolo tempo e angolo
dt = lag / RATE
# Limita l'argomento di arcsin tra -1 e 1 per evitare errori
sin_argument = (v * dt) / d
if abs(sin_argument) <= 1.0:
angle_rad = math.asin(sin_argument)
angle_deg = math.degrees(angle_rad)
# Visualizzazione a barre dinamica
bar_position = int(angle_deg / 10) + 9
display = ["-"] * 19
display[bar_position] = "O"
print(f"[{''.join(display)}] Angolo: {angle_deg:6.1f}°", end="\r")

except KeyboardInterrupt:
print("\nFermato dall'utente.")
finally:
proc.terminate()

 

Nessun commento:

Posta un commento

Microfoni Kinect1

Ho trovato quasi per caso su Internet che il Kinect 1 ha un array di 4 microfoni che permettono di determinare la direzione del suono (ed es...