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

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()