ESP8266 软件实现 Delta-sigma(ΔΣ)调制器 并通过I2S接口输出编码流

时间:2023-03-08 23:33:33
ESP8266 软件实现 Delta-sigma(ΔΣ)调制器 并通过I2S接口输出编码流

一、关于Delta-sigma(ΔΣ)调制器

  Delta-sigma(ΔΣ)调制器是Delta-sigma转换器的核心部件。如下所示为一个简单的一阶Delta-sigma调制器,该调制器产生一个1bit比特流。将该比特流脉冲输入低通滤波器,从滤波器输出端口可以获得比特流信号的平均电平,该电平代表了调制器的输入电平。

ESP8266 软件实现 Delta-sigma(ΔΣ)调制器 并通过I2S接口输出编码流

  一阶Delta-sigma调制器的实例时序如下:

ESP8266 软件实现 Delta-sigma(ΔΣ)调制器 并通过I2S接口输出编码流

  在该实例中,时钟频率(此处等于采样率)为输入信号的64倍。根据采样定理,转换器需要至少2倍于有效信号最高频率的采样率,而Delta-sigma转换器则需要比传统转换器高得多的采样频率来产生足够数量的比特流脉冲,相同条件下提高调制器的时钟频率,则可以获得更高的精度。

二、降低量化噪声

  可以看出,比特流的平均电平(经过低通滤波后的电平)只会在某个精度范围内接近于原始电平,而永远不会完全相同,输出信号永远叠加着量化噪声。

  一种降低量化噪音的方法是:增加时钟频率(过采样)。例如,假设现有一个带宽为20kHz的音频信号,一个典型的PCM采样率为48kHz,而典型的Delta-sigma转换器的时钟频率高达 64 x 48kHz = 3.072 MHz,即相当于64倍的过采样。

  另一种更好的解决方案是:采用高阶的Delta-sigma调制器。一般来说,一阶调制器在高频段产生较多噪声功率,如果输入信号电平接近动态范围,则这种效应最为显著。采样高阶调制器可获得较一阶调制器更低的噪声。

三、二阶Delta-sigma调制器

  典型的二阶delta-sigma调制器如下图所示:

ESP8266 软件实现 Delta-sigma(ΔΣ)调制器 并通过I2S接口输出编码流

  该类型的调制器产生的比特流更加接近于理想的比例脉冲信号,因此可带来如下优势:增大输入信号带宽、降低采样频率、增加转换精度(抑制量化噪声)。

  理论上高于2阶的delta-sigma调制器是可行的,但无法通过简单地增加差分积分单元实现,其根本原因是由2个以上积分器产生的相位误差将使降低系统的稳定性。

  成熟的商业的音频ADC往往采用5阶甚至以上的delta-sigma调制器,使用64倍的过采样,其架构与本文所述有所不同,但基本原理是相同的。

四、软件实现二阶Delta-sigma调制器

  通过上文对二阶delta-sigma调制器的描述,我们可以容易得出该调制器的数字实现。这里采用C语言实现DSP(digital signal process)。

 int32_t w;                     /* Data Flow path */
 , i2v = ;   /* Integrator 1 and 2 */
 ;      /* Latch */

  对每个比特位的处理过程如下。对输入电平w迭代n次可得出任意采样率的调制输出。

 #define HW (32767)

 [Input: w]

 ) w -= HW; else w += HW; /* Difference 1 */
 w += i1v; i1v = w; /* Integrator 1 */
 ) w -= HW; else w += HW; /* Difference 2 */
 w += i2v; i2v = w; /* Integrator 2 */
 latch_reg = w;   /* Latch */
 b = (w > );     /* Comparator */

 [Output to bitstream: b]

五、ESP8266的I2S输出端口

  由于I2S接口具有串行数据连续传输而不断流的特性,因此在提高时钟频率的情况下,I2S接口可用于输出delta-sigma调制器的比特流。除I2S接口外,其它具有连续串行输出特性的接口同样可以承担输出比特流的工作。

  ESP8266芯片提供了I2S PHY及接口,可配置工作于较高的时钟频率,SER并串转换器(串行移位器)可将并行字节通过端口串行地发送出去。对于比特流输出的实现而言,我们只关心I2S的数据输出端口SDAT,至于LRCLK和BCLK信号则完全抛弃。将I2S传输格式配置为每声道16bit全数据(双声道),则每个I2S传送周期(传输一次所有声道的PCM采样)可发送32个比特位。

  这里先将delta-sigma调制输出的比特流的每32位伪装成4字节的PCM音频采样数据,通过DMA传输到I2S总线,而I2S模块中的ser模块再将伪装的PCM采样数据串行化输出,最终从SDAT端口得到完整的比特流信号。

  调制得出的比特流可预先压入FIFO缓冲器,在I2S时钟的驱动下,以慢于软件调制速率的节拍从FIFO取出数据,这样就保证了输出比特流的连续性。

  函数samp_to_delta_sigma()实现了将输入电平s调制为32bit比特流。简单计算调制器的采样率如下:

    Fs = Fs(Input) * 32,其中Fs(Input)为输入数字信号的采样率。

  对于PCM音频数据,若原始采样率为48kHz,则该delta-sigma调制器的采样率可达:

    Fs = 48kHz * 32 = 1.536MHz

  则要求I2S总线的BCLK时钟频率至少达到:

    Fmin = 1.536MHz

 int32_t
 samp_to_delta_sigma(short s)
 {
   int w;
   , i2v = ;
   ;

   int i;
   ;

   ; i<; i++)
     {
       val<<=;
       w=s;
       ) w -= HW; else w += HW; /* Difference 1 */
       w += i1v; i1v = w; /* Integrator 1 */
       ) w -= HW; else w += HW; /* Difference 2 */
       w += i2v; i2v = w; /* Integrator 2 */
       latch_reg = w;   /* Latch */
       ) val|=; /* comparator */
     }
   return val;
 }

  从上面简单计算可以看出,当调制器迭代次数与I2S传输周期的有效位数相同时,将I2S驱动请求的采样率配置为输入信号的原始采样率即可确保时钟正确。

  本文采用espressif NONOS SDK提供的I2S驱动库。首先调用I2sInit()初始化I2S接口,再调用I2sSetRate()设置采样率。对于每个输入信号采样s,通过调用i2sPushSample( samp_to_delta_sigma(s) )即可实现delta-sigma调制和比特流输出。

  如下为一个实例,该例程调制采样率为48kHZ的PCM音频信号并输出:

 I2sInit();
 I2sSetRate(, );

 ; i < size; i++)
   i2sPushSample( samp_to_delta_sigma(s[i]) );

六、CPU负载评估 

  仍以原始采样率为48kHz的PCM音频数据为例,从第五节已经得出,FIFO输出侧(I2S端口)最小带宽为 W1 = 1.536 * 10^(6) / 1024^2 ≈ 1.5 (MBits/s)。对于FIFO输入侧(软件调制器),为便于计算,先设CPU执行一次samp_to_delta_sigma()函数的平均用时为T0 (s),则软件调制的输出带宽为 W2 = 32 / T0 / 1024^2 (MBits/s)

  若系统能稳定工作,则要求I2S端口实际带宽Wf与W1、W2满足如下关系(正常情况下W1 = Wf,以确保正确还原比特流信号的时钟频率):

    W1 <= Wf < W2

  一旦条件满足,CPU将得到空闲时间:

    Tfree = 1 / [(W2 - Wf) * 1024^2] (s)

  这是因为系统运行中,除起始状态外FIFO将永远保持非空状态。Tfree可以代表用于运行其它任务的空闲时间长度(包括任务调度切换的时间)。若其它操作占用超过Tfree的运行时间,则可能导致FIFO输入侧带宽不足,从而造成FIFO下溢出,使得输出中断。

  T0的决定因素非常复杂,需要考虑生成的汇编指令、整个CPU的运行状态(如时钟主频,cache状态等)和输入的数字信号,因此只能得出平均值T0,将T0代入上式即可得出近似的Tfree时间。

七、应用价值

  在音频应用领域,该方法可通过简单的一阶RC滤波电路,直接从I2S接口得出模拟音频信号,从而省去成本较高的DAC芯片。除此之外,加入简单的功率输出和滤波电路,即可实现Class-D数字功放,如下图所示。

ESP8266 软件实现 Delta-sigma(ΔΣ)调制器 并通过I2S接口输出编码流