生成用于验证 TDM slot 配置的波形
Qidi Huang 2025.11.17
使用逻辑分析仪测量 TDM 的 BCLK、FSYNC、SDO引脚上的信号,可以验证 TDM slot 配置及输出是否正确。不过,我们不能使用常规正弦波进行测量,而是要使用一种特殊波形。在这种波形上:有信号的 slot 输出 0xAA;无信号的 slot 输出 0x00。两种 slot 交替,即可在逻辑分析仪上分辨出 slot 个数和宽度。
这种波形正常人也用不上,所以一般需要工程师自己生成。
以下代码可以生成一段 30秒、单声道、16位、48000赫兹 的测试波形:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#pragma pack(push, 1) // Ensure no padding in WAV header structs
typedef struct {
char chunkID[4]; // "RIFF"
uint32_t chunkSize;
char format[4]; // "WAVE"
} RIFFHeader;
typedef struct {
char subChunk1ID[4]; // "fmt "
uint32_t subChunk1Size; // 16 for PCM
uint16_t audioFormat; // 1 = PCM
uint16_t numChannels;
uint32_t sampleRate;
uint32_t byteRate;
uint16_t blockAlign;
uint16_t bitsPerSample;
} FmtSubchunk;
typedef struct {
char subChunk2ID[4]; // "data"
uint32_t subChunk2Size;
} DataSubchunk;
#pragma pack(pop)
int main() {
const char *filename = "tdmCalibration_1c_16b_48k_30s.wav";
FILE *fp = fopen(filename, "wb");
if (!fp) {
perror("Failed to open output file");
return 1;
}
// WAV parameters
uint16_t numChannels = 1;
uint32_t sampleRate = 48000;
uint16_t bitsPerSample = 16;
uint32_t durationSec = 30;
uint32_t numSamples = sampleRate * durationSec;
uint32_t dataSize = numSamples * numChannels * (bitsPerSample / 8);
// Prepare WAV header
RIFFHeader riff = {
{'R','I','F','F'},
36 + dataSize, // chunkSize = 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size)
{'W','A','V','E'}
};
FmtSubchunk fmt = {
{'f','m','t',' '},
16, // PCM
1, // audioFormat = 1 (PCM)
numChannels,
sampleRate,
sampleRate * numChannels * (bitsPerSample / 8),
(uint16_t)(numChannels * (bitsPerSample / 8)),
bitsPerSample
};
DataSubchunk data = {
{'d','a','t','a'},
dataSize
};
// Write headers
fwrite(&riff, sizeof(riff), 1, fp);
fwrite(&fmt, sizeof(fmt), 1, fp);
fwrite(&data, sizeof(data), 1, fp);
// Create 0xAA-filled audio buffer
uint8_t sampleBytes[2] = {0xAA, 0xAA}; // 16bit = 2bytes
for (uint32_t i = 0; i < numSamples; i++) {
fwrite(sampleBytes, sizeof(sampleBytes), 1, fp);
}
fclose(fp);
printf("WAV file generated: %s\n", filename);
return 0;
}
如果想生成多声道的测试波形,可以使用如下代码(按需修改 numChannels 变量值):
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#pragma pack(push, 1)
typedef struct {
char chunkID[4]; // "RIFF"
uint32_t chunkSize;
char format[4]; // "WAVE"
} RIFFHeader;
typedef struct {
char subChunk1ID[4]; // "fmt "
uint32_t subChunk1Size; // 16 for PCM
uint16_t audioFormat; // 1 = PCM
uint16_t numChannels;
uint32_t sampleRate;
uint32_t byteRate;
uint16_t blockAlign;
uint16_t bitsPerSample;
} FmtSubchunk;
typedef struct {
char subChunk2ID[4]; // "data"
uint32_t subChunk2Size;
} DataSubchunk;
#pragma pack(pop)
int main() {
const char *filename = "12ch_output.wav";
FILE *fp = fopen(filename, "wb");
if (!fp) {
perror("Failed to open output file");
return 1;
}
// WAV parameters
const uint16_t numChannels = 12;
const uint32_t sampleRate = 48000;
const uint16_t bitsPerSample = 16;
const uint32_t durationSec = 30;
const uint32_t numSamples = sampleRate * durationSec;
const uint32_t bytesPerSample = bitsPerSample / 8;
const uint32_t frameSize = numChannels * bytesPerSample; // 12 * 2 = 24 bytes
const uint32_t dataSize = numSamples * frameSize;
// Prepare headers
RIFFHeader riff = {
{'R','I','F','F'},
36 + dataSize,
{'W','A','V','E'}
};
FmtSubchunk fmt = {
{'f','m','t',' '},
16,
1, // PCM
numChannels,
sampleRate,
sampleRate * frameSize, // byteRate
frameSize, // blockAlign
bitsPerSample
};
DataSubchunk data = {
{'d','a','t','a'},
dataSize
};
// Write headers
fwrite(&riff, sizeof(riff), 1, fp);
fwrite(&fmt, sizeof(fmt), 1, fp);
fwrite(&data, sizeof(data), 1, fp);
// Build one 12-channel interleaved frame
uint8_t frame[24]; // 12 channels × 2 bytes
for (int ch = 0; ch < numChannels; ch++) {
if (ch % 2 == 0) {
// Even channel: 0xAAAA
frame[ch * 2 + 0] = 0xAA;
frame[ch * 2 + 1] = 0xAA;
} else {
// Odd channel: 0x0000
frame[ch * 2 + 0] = 0x00;
frame[ch * 2 + 1] = 0x00;
}
}
// Write frames
for (uint32_t i = 0; i < numSamples; i++) {
fwrite(frame, sizeof(frame), 1, fp);
}
fclose(fp);
printf("Generated 12-channel WAV: %s\n", filename);
return 0;
}
本文来自博客园,作者:Qidi_Huang,转载请注明原文链接:https://www.cnblogs.com/qidi-huang/p/19232940

浙公网安备 33010602011771号