采集卡解析数据及例程(Python)

2026年06月11日 13:04

关键词: DAS示例程序

采集卡数据解析流程图

采集卡有UDP网络协议的,也有PCIE接口的。所以从采集卡读取连续字节流每张卡会有一点差异。解析DAS数据的逻辑流程基本一样,以下是以GY-DAQ-2480这张卡为例说明。

Image

示例代码(Python)

  • 采集卡的输出数据,是按交替方式存储的:
    • sel=1(双通道原始数据):ch1, ch2, ch1, ch2, ...
    • sel=2(通道 1 幅度相位):幅度1, 相位1, 幅度1, 相位1, ...
    • sel=3(双通道相位数据):相位1, 相位2, 相位1, 相位2, ...
  • 数据类型:
    • 原始 / 相位:short(有符号 16 位)
    • 幅度:unsigned short(无符号 16 位)
  • 相位数据需 /512.0 归一化,才能得到弧度值,也可直接当音频用。


import numpy as np
import matplotlib.pyplot as plt
import os
import wave

# ========== 1. 配置参数 ==========
samples_per_frame = 2560   # 单帧采样点数(你之前的配置)
sel_mode = 3               # 采集卡模式:1/2/3,根据实际使用的模式修改
play_rate = 20000          # 音频采样率,和采集卡保持一致
file_name = '2026-03-06_10-41-36.bin'  # 你的bin文件名从采集卡保存的文件。

# 获取脚本路径
current_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(current_dir, file_name)

# ========== 2. 读取原始二进制数据 ==========
with open(file_path, 'rb') as f:
    buffer = f.read()

# ========== 3. 根据sel_mode解析数据 ==========
if sel_mode == 1:
    # 模式1:双通道原始数据,交替存储:ch1, ch2, ch1, ch2...
    data = np.frombuffer(buffer, dtype=np.int16)  # 原始数据是short类型
    ch1 = data[0::2]  # 取偶数索引(0,2,4...)
    ch2 = data[1::2]  # 取奇数索引(1,3,5...)
    print(f"模式1解析完成:ch1长度={len(ch1)}, ch2长度={len(ch2)}")

elif sel_mode == 2:
    # 模式2:通道1幅度相位,交替存储:幅度1, 相位1, 幅度1, 相位1...
    data_u16 = np.frombuffer(buffer, dtype=np.uint16)  # 幅度是unsigned short
    data_i16 = np.frombuffer(buffer, dtype=np.int16)   # 相位是short
    amp1 = data_u16[0::2]  # 幅度:偶数索引
    phase1 = data_i16[1::2] / 512.0  # 相位:奇数索引,除以512归一化到弧度
    print(f"模式2解析完成:amp1长度={len(amp1)}, phase1长度={len(phase1)}")

elif sel_mode == 3:
    # 模式3:双通道相位数据,交替存储:相位1, 相位2, 相位1, 相位2...
    data = np.frombuffer(buffer, dtype=np.int16)
    phase1 = data[0::2] / 512.0  # 通道1相位
    phase2 = data[1::2] / 512.0  # 通道2相位
    print(f"模式3解析完成:phase1长度={len(phase1)}, phase2长度={len(phase2)}")

else:
    raise ValueError("sel_mode 只能是 1/2/3")

# ========== 4. 抽取指定帧位置的数据(对应你之前的pos=128) ==========
# 以模式1为例,抽取ch1的pos=128列(和你之前的逻辑对齐)
pos = 128  # 你之前设置的播放位置
if sel_mode == 1:
    # 重塑为[帧数, 单帧采样点数/2],因为每帧是ch1+ch2交替
    # 注:samples_per_frame 是原始每帧的总点数(含ch1和ch2)
    ch1_frames = ch1.reshape(-1, samples_per_frame // 2)
    # 自己解调的代码.....

elif sel_mode == 3:
    # 模式3,抽取phase1的pos=128列(相位数据直接当音频用)
    phase1_frames = phase1.reshape(-1, samples_per_frame // 2)
    phase1_pos_data = phase1_frames[:, pos]
    s_normalized = phase1_pos_data / np.max(np.abs(phase1_pos_data))
    audio_int16 = (s_normalized * 32767).astype(np.int16)

# ========== 5. 保存为WAV文件(可选) ==========
def save_wave(filename, data, rate):
    with wave.open(filename, 'wb') as wf:
        wf.setnchannels(1)        # 单声道
        wf.setsampwidth(2)       # 16位
        wf.setframerate(rate)    # 采样率
        wf.writeframes(data.tobytes())

# 示例:保存抽取后的音频
if 'audio_int16' in locals():
    save_wave('output.wav', audio_int16, play_rate)
    print("音频已保存为 output.wav")

# ========== 6. 绘制波形(可选) ==========
plt.figure(figsize=(12, 4))
if sel_mode == 1:
    plt.plot(ch1_pos_data, label='ch1 pos=128')
elif sel_mode == 3:
    plt.plot(phase1_pos_data, label='phase1 pos=128')
plt.legend()
plt.title("Extracted Waveform")
plt.show()

联系电话 13427781756