STM32F1 ADC采集录音存SD卡

目录

  • 前言
  • TP79录音功能解析
  • STM32如何得到8K采样率
    • 例子
  • WAV音频文件解析
  • PCM格式
  • WAV格式
  • c语言中wav数据结构的构成
  • wav文件格式实例分析
    • WAVE_HEADER
    • WAVE_FMT
    • WAVE_DATA
    • DATA

前言

更多技术整理,欢迎关注本人博客www.tomtwos.com

参考资料:
PCM、WAV格式介绍及用C语言实现PCM转WAV

TP79录音功能解析

以TYT TP79机型的录音功能为例,采用8KHz采样率,8bit采样值,未用WT2000等录音芯片,直接以8KHz采样率采集录音脚的adc值,在TIM定时器中断中存入SD卡,播放也是以8KHz速率读取SD卡中的WAV文件的PCM值,通过DAC实时播放

STM32如何得到8K采样率

  1. 查阅得到TIMx的输入时钟(通过芯片手册和程序查阅)
  2. 通过定时器的自动重装值TIM_Period和时钟预分频数TIM_Prescaler 2个参数设置所需频率的采样率。

公式:定时器时钟/((TIM_Prescaler+1)*(TIM_Period+1))

例子

TYT TP79的输入时钟频率为72MHz,设置的预分频数为4499,自动装载值为1,通过公式72000k/(4500*2)

img-KswTro2w-1585561890552

STM32F1 ADC采集录音存SD卡_第1张图片

WAV音频文件解析

  • 每个WAV文件的头四个字节便是“RIFF”。
  • WAV文件由文件头和数据体两大部分组成。其中文件头又分为RIFF/WAV文件标识段和声音数据格式说明段两部分。
  • 常见的声音文件主要有两种,分别对应于单声道(11.025KHz采样率、8Bit的采样值)和双声道(44.1KHz采样率、16Bit的采样值)。
  • 单声道声音文件,采样数据为八位的短整数(short int 00H-FFH); 而对于双声道立体声声音文件,每次采样数据为一个16位的整数(int),高八位和低八位分别代表左右两个声道。
  • WAV文件数据块包含以脉冲编码调制(PCM)格式表示的样本
  • 在单声道WAV文件中,声道0代表左声道,声道1代表右声道。在多声道WAV文件中,样本是交替出现的。
  • 以后用到PCM录音存储功能直接拿TP79的代码移植,对应WAV的数据结构和初始化代码对比此文档应用

PCM格式

PCM(Pulse Code Modulation)也被称为 脉码编码调制。

PCM中的声音数据没有被压缩,如果是单声道的文件,采样数据按时间的先后顺序依次存入。(它的基本组织单位是BYTE(8bit)或WORD(16bit))

WAV格式

WAVE文件格式是Microsoft的RIFF规范的一个子集,用于存储多媒体文件。

WAVE文件通常只是一个具有单个“WAVE”块的RIFF文件,该块由两个子块("fmt"子数据块和"data"子数据块)组成。其中data块存的就是PCM格式的数据。
STM32F1 ADC采集录音存SD卡_第2张图片

c语言中wav数据结构的构成

typedef struct{
    char          ChunkID[4];//内容为"RIFF"
    unsigned long ChunkSize;//存储文件的字节数(不包含ChunkID和ChunkSize这8个字节)
    char          Format[4];//内容为"WAVE"
}WAVE_HEADER;

typedef struct{
    char           Subchunk1ID[4];//内容为"fmt"
    unsigned long  Subchunk1Size;//存储该子块的字节数(不含前面的Subchunk1ID和Subchunk1Size这8个字节)
    unsigned short AudioFormat;//存储音频文件的编码格式,例如若为PCM则其存储值为1,若为其他非PCM格式的则有一定的压缩。
    unsigned short NumChannels;//通道数,单通道(Mono)值为1,双通道(Stereo)值为2,等等
    unsigned long  SampleRate;//采样率,如8k,44.1k等
    unsigned long  ByteRate;//每秒存储的bit数,其值=SampleRate * NumChannels * BitsPerSample/8
    unsigned short BlockAlign;//块对齐大小,其值=NumChannels * BitsPerSample/8
    unsigned short BitsPerSample;//每个采样点的bit数,一般为8,16,32等。
}WAVE_FMT;

typedef struct{
    char          Subchunk2ID[4];//内容为“data”
    unsigned long Subchunk2Size;//内容为接下来的正式的数据部分的字节数,其值=NumSamples * NumChannels * BitsPerSample/8
}WAVE_DATA;

typedef struct{
    WAVE_HEADER    wave_head;
    WAVE_FMT       wave_fmt;
    WAVE_DATA      wave_data;
}WAVE_FORMAT;

wav文件格式实例分析

52 49 46 46 0A 06 01 00 57 41 56 45 66 6D 74 20 12 00 00 00 01 00 02 00 44 AC 00 00 10 B1 02 00 04 00 10 00 64 61 74 61 D8 05 01 00 00 00 00 00 FF FF 00 00 FE FF FE FF 00 00 00 00 FE FF FE FF 00 00

WAVE_HEADER

  • 52 49 46 46 4字节 "RIFF"标志符
  • 0A 06 01 00 4字节 0x00 01 06 0A 文件长度(倒序储存)
  • 57 41 56 45 4字节 "WAVE"标志符

WAVE_FMT

  • 66 6D 74 20 4字节 "fmt "标志符
  • 12 00 00 00 4字节 0x12;Sizeof(PCMWAVEFORMAT)
  • 01 00 2字节 1;格式类型 WAVE_FORMAT_PCM 1表示PCM格式的数据
  • 02 00 2字节 2;通道数 单声道为1
  • 44 AC 00 00 4字节 44100;采样频率(每秒样本数)
  • 10 B1 02 00 4字节 0x10B10000;每秒数据量;利用此值估计缓冲区大小
  • 04 00 2字节 数据块的调整数(按字节算的)
  • 10 00 2字节 每样本的数据位数

WAVE_DATA

  • 64 61 74 61 4字节 "data"数据标记符
  • D8 05 01 00 4字节 0x00 01 05 D8; 语音数据大小

DATA

00 00 00 00 FF FF 00 00 FE FF FE FF 00 00 00 00 FE FF FE FF 00 00 具体的PCM数据

你可能感兴趣的:(MCU)