85|2

11

帖子

2

TA的资源

一粒金砂(中级)

楼主
 

【Follow me第二季第4期】在Arduino下使用SD卡录制声音 [复制链接]

  本帖最后由 eew_9XVJps 于 2024-12-3 09:02 编辑

自定任务:Arduino Nano RP2040 Connect板载的PDM麦克风实现录音功能

       看到板载有麦克风为什么不试一下录制声音呢,因此想通过板载的PDM麦克风实现声音拾取,并将收集到的数据以WAV格式形式存储在SD卡中。SD卡通过SPI接口实现与主控板通讯,SPI引脚直接使用了默认引脚。

 

       我使用的SD卡外置模块为5V供电,需要将主控板的VBUS焊盘连接上来进行供电,否则3V3无法启动。

       流程顺序大体如下:

 

目前程序还是有点问题不知道是出在哪里,录音的长度和设定长度一致,但是播放录制的程序明显速度变快了,哪位大佬有空帮我看看问题出在哪里了,程序如下:

#include <PDM.h>
#include "wave.h"
#include <SPI.h>
#include "SdFat.h"
const int chipSelect = 10;

// default number of output channels
static const char channels = 1;

// default PCM output frequency
static const int frequency = 20000;
// Buffer to read samples into, each sample is 16-bits
short sampleBuffer[128];
const int record_time = 30;  // second
const char filename[] = "/record.wav";
const int waveDataSize = record_time * 40000;
char partWavData[1024];
// Number of audio samples read
volatile int samplesRead;

FsFile file;  // 录音文件
SdFs sd;
void setup() {
  Serial.begin(9600);

  delay(2000);
  if(!sd.begin(SdSpiConfig(chipSelect, DEDICATED_SPI, SD_SCK_MHZ(16))))//初始化SD
  {
    Serial.println(F("sd init error"));
    return;
  }
  sd.remove(filename);
  file = sd.open(filename, O_WRITE|O_CREAT);
  if(!file)
  {
    Serial.println("crate file error");
    return;
  }
  // Configure the data receive callback
  auto header = CreateWaveHeader(1, 20000, 16);
  header.riffSize = waveDataSize + 44 - 8;
  header.dataSize = waveDataSize;
  file.write(&header,44);
  PDM.onReceive(onPDMdata);

  // Optionally set the gain
  // Defaults to 20 on the BLE Sense and 24 on the Portenta Vision Shield
  PDM.setGain(10);

  // Initialize PDM with:
  // - one channel (mono mode)
  // - a 16 kHz sample rate for the Arduino Nano 33 BLE Sense
  // - a 32 kHz or 64 kHz sample rate for the Arduino Portenta Vision Shield
  if (!PDM.begin(channels, frequency)) {
    Serial.println("Failed to start PDM!");
    while (1);
  }
  else{
    Serial.println("start");
  }
}
int count = waveDataSize/128;
void loop() {
  // Wait for samples to be read
  if(count==0){
    samplesRead=0;
    file.close();
    Serial.println("finish");
  }
  if (samplesRead) {
    file.write((const byte*)sampleBuffer, 128);
    count--;
    // Clear the read count
    samplesRead = 0;
  }
  // if (samplesRead) {
  //   Serial.println(samplesRead);
  //   samplesRead=0;
  // }

}

/**
 * Callback function to process the data from the PDM microphone.
 * NOTE: This callback is executed as part of an ISR.
 * Therefore using `Serial` to print messages inside this function isn't supported.
 * */
void onPDMdata() {
  // Query the number of available bytes
  int bytesAvailable = PDM.available();

  // Read into the sample buffer
  PDM.read(sampleBuffer, bytesAvailable);//每次64样本

  // 16-bit, 2 bytes per sample
  samplesRead = bytesAvailable / 2;
}

对应的WAVE文件内容

#include "wave.h"

WAV_HEADER CreateWaveHeader(int numChannels,                    //声道数
                            unsigned int sampleRate,            //采样率
                            unsigned short bitsPerSample)       //采样位宽
{
  WAV_HEADER header;
  header.riffSize = 0;
  header.numChannels = numChannels;
  header.sampleRate = sampleRate;
  header.bitsPerSample = bitsPerSample;
  header.bytesPerSecond = sampleRate * numChannels * bitsPerSample /8 ;
  header.blockAlign = numChannels * bitsPerSample/8;
  header.dataSize = 0;
  return header;
}

效果图如下,动态效果见视频:

 
59820604

最新回复

有更新了吗?换成14k就好了?     详情 回复 发表于 昨天 17:28
点赞(1) 关注
 
 

回复
举报

104

帖子

5

TA的资源

一粒金砂(中级)

沙发
 

有更新了吗?换成14k就好了?

 
个人签名尽吾志也而不能至者,可以无悔矣。——王安石
 
 
 

回复

11

帖子

2

TA的资源

一粒金砂(中级)

板凳
 
yilonglucky 发表于 2024-12-3 17:28 有更新了吗?换成14k就好了?  

是的换成14000速率就好了,下面是新录制的视频

改之后

就是没搞明白明明麦克风和WAVE文件里面设置的声道数和速度都一致为啥只有14000采样率才正常。

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表