2026年06月11日 13:04
采集卡有UDP網(wǎng)絡(luò)協(xié)議的,也有PCIE接口的。所以從采集卡讀取連續(xù)字節(jié)流每張卡會有一點差異。解析DAS數(shù)據(jù)的邏輯流程基本一樣,以下是以GY-DAQ-2480這張卡為例說明。

sel=1(雙通道原始數(shù)據(jù)):ch1, ch2, ch1, ch2, ...sel=2(通道 1 幅度相位):幅度1, 相位1, 幅度1, 相位1, ...sel=3(雙通道相位數(shù)據(jù)):相位1, 相位2, 相位1, 相位2, ...short(有符號 16 位)unsigned short(無符號 16 位)/512.0 歸一化,才能得到弧度值,也可直接當(dāng)音頻用。import numpy as np
import matplotlib.pyplot as plt
import os
import wave
# ========== 1. 配置參數(shù) ==========
samples_per_frame = 2560 # 單幀采樣點數(shù)(你之前的配置)
sel_mode = 3 # 采集卡模式:1/2/3,根據(jù)實際使用的模式修改
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. 讀取原始二進制數(shù)據(jù) ==========
with open(file_path, 'rb') as f:
buffer = f.read()
# ========== 3. 根據(jù)sel_mode解析數(shù)據(jù) ==========
if sel_mode == 1:
# 模式1:雙通道原始數(shù)據(jù),交替存儲:ch1, ch2, ch1, ch2...
data = np.frombuffer(buffer, dtype=np.int16) # 原始數(shù)據(jù)是short類型
ch1 = data[0::2] # 取偶數(shù)索引(0,2,4...)
ch2 = data[1::2] # 取奇數(shù)索引(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] # 幅度:偶數(shù)索引
phase1 = data_i16[1::2] / 512.0 # 相位:奇數(shù)索引,除以512歸一化到弧度
print(f"模式2解析完成:amp1長度={len(amp1)}, phase1長度={len(phase1)}")
elif sel_mode == 3:
# 模式3:雙通道相位數(shù)據(jù),交替存儲:相位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. 抽取指定幀位置的數(shù)據(jù)(對應(yīng)你之前的pos=128) ==========
# 以模式1為例,抽取ch1的pos=128列(和你之前的邏輯對齊)
pos = 128 # 你之前設(shè)置的播放位置
if sel_mode == 1:
# 重塑為[幀數(shù), 單幀采樣點數(shù)/2],因為每幀是ch1+ch2交替
# 注:samples_per_frame 是原始每幀的總點數(shù)(含ch1和ch2)
ch1_frames = ch1.reshape(-1, samples_per_frame // 2)
# 自己解調(diào)的代碼.....
elif sel_mode == 3:
# 模式3,抽取phase1的pos=128列(相位數(shù)據(jù)直接當(dāng)音頻用)
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()