Arduino:如何将模拟信号存储到 SD 卡上的 wav 文件的数据块? WAV 文件已创建但没有声音且长度为 0

问题描述 投票:0回答:0

我想做什么: 我正在使用 Arduino Due 构建录音机。我有一个带有音频信号的接收器和一个连接到它的 SD 模块。当按下按钮(高电平有效)时,我想录制音频并将其保存在 SD 卡上。

问题: 我正在使用 Arduino DUE 录制音频文件并将其保存到 SD 卡中。 ADC 位转换为 12 位。

我使用了这个 wav 文件“模板”->如何将 Arduino 的模拟输入读数从草图转换为 .WAV 以创建文件并将其写入我的 SD 卡。

我还发现另一篇文章使用这个 wav 文件“模板”有同样的问题,但找不到问题的解决方案/答案。 -> Arduino:如何将模拟信号存储到 wav 文件的数据块?

波形文件创建正确,没有损坏,但没有声音,长度为0,但写入了字节。例如:wav 文件将有 13 KB,但长度为 0:00。

这是我的 Arduino 代码:

#include <SPI.h>
#include <SD.h>

/// The first 4 byte of a wav file should be the characters "RIFF" */
char chunkID[4] = { 'R', 'I', 'F', 'F' };
/// 36 + SubChunk2Size
uint32_t chunkSize = 36;  // You Don't know this until you write your data but at a minimum it is 36 for an empty file
/// "should be characters "WAVE"
char format[4] = { 'W', 'A', 'V', 'E' };
/// " This should be the letters "fmt ", note the space character
char subChunk1ID[4] = { 'f', 'm', 't', ' ' };
///: For PCM == 16, since audioFormat == uint16_t
uint32_t subChunk1Size = 16;
///: For PCM this is 1, other values indicate compression
uint16_t audioFormat = 1;
///: Mono = 1, Stereo = 2, etc.
uint16_t numChannels = 1;
///: Sample Rate of file, ARDUINO DUE IS 1MHZ ??????
uint32_t sampleRate = 1 * 10^6;// 50000;
///: 8 bits = 8, 16 bits = 16, ARDUINO DUE ADC IS 10 OR 12 BITS !!!!!!!!
uint16_t bitsPerSample = 16;
///: SampleRate * NumChannels * BitsPerSample/8
uint32_t byteRate = sampleRate * bitsPerSample / 8;
///: The number of byte for one frame NumChannels * BitsPerSample/8
uint16_t blockAlign = numChannels * bitsPerSample / 8;
///: Contains the letters "data"
char subChunk2ID[4] = { 'd', 'a', 't', 'a' };
///: == NumSamples * NumChannels * BitsPerSample/8  i.e. number of byte in the data.
uint32_t subChunk2Size = 0;  // You don't know this until you write your data

const int ADC_BIT_RESOLUTION = 12;  // ADC bit resolution
const int chipSelect = 10;          // chip select pin
const int squelch = 39;             // squelch pin 

int MIN_DATA_VALUE = 0;
int MAX_DATA_VALUE = pow(2, ADC_BIT_RESOLUTION); 

File wavFile;
char filename[] = "file.wav";  // file to write to

void writeWavHeader() {
  wavFile.seek(0);
  wavFile.write(chunkID, 4);
  wavFile.write((byte*)&chunkSize, 4);
  wavFile.write(format, 4);
  wavFile.write(subChunk1ID, 4);
  wavFile.write((byte*)&subChunk1Size, 4);
  wavFile.write((byte*)&audioFormat, 2);
  wavFile.write((byte*)&numChannels, 2);
  wavFile.write((byte*)&sampleRate, 4);
  wavFile.write((byte*)&byteRate, 4);
  wavFile.write((byte*)&blockAlign, 2);
  wavFile.write((byte*)&bitsPerSample, 2);
  wavFile.write(subChunk2ID, 4);
  wavFile.write((byte*)&subChunk2Size, 4);
}

void writeDataToWavFile(int data) {
  int16_t sampleValue = map(data, MIN_DATA_VALUE, MAX_DATA_VALUE, -32767, 32767);

  ///: == NumSamples * NumChannels * BitsPerSample/8  i.e. number of byte in the data.
  // subChunk2Size += numSamples * numChannels * bitsPerSample/8;
  subChunk2Size += numChannels * bitsPerSample / 8;
  wavFile.seek(40);
  wavFile.write((byte*)&subChunk2Size, 4);

  wavFile.seek(4);
  chunkSize = 36 + subChunk2Size;
  wavFile.write((byte*)&chunkSize, 4);

  wavFile.seek(wavFile.size() - 1);
  wavFile.write((byte*)&sampleValue, 2);
}

int setupSD() {  // set up SD card
  Serial.print("\nInitializing SD card...");
  if (!SD.begin()) {
    Serial.println("initialization failed!");
    return 0;
  }
  Serial.println("initialization done.");
  return 1;
}

void readSD(char filename[]) {  // read SD file
  // re-open the file for reading
  wavFile = SD.open(filename);
  if (wavFile) {
    Serial.println(filename);

    // read from the file until there's nothing else in it:
    while (wavFile.available()) {
      Serial.write(wavFile.read());
    }
    Serial.println();
    wavFile.close();
  } else {  // if the file didn't open, print an error
    Serial.print("readSD(): error opening ");
    Serial.print(filename);
    Serial.println(".");
  }
}

int getRecordData() { // ADC
  while ((ADC->ADC_ISR & 0x80) != 0x80) {}  // wait for ADC CH7 end of conversion
  int in_ADC0 = ADC->ADC_CDR[7];            // read CH7 ADC and store in in_ADC0;
  return in_ADC0;
}


void setup() {
  Serial.begin(9600);             // set baud rate
  //pinMode(squelch, INPUT_PULLDOWN); // set pulldown resistor
  pinMode(squelch, INPUT);        // set squelch as input (active high)

  // ADC setup
  ADC->ADC_MR |= 0x80;                       // mode register - select free running mode
  ADC->ADC_CHER = 0x80;                      // channel enable register (A0 = CH7)
  ADC->ADC_CR = 0x02;                        // control register - begin conversions
  ADC->ADC_MR |= 0x27;                       // set prescale = 38 to get ADCClokc = 50kHz
  analogReadResolution(ADC_BIT_RESOLUTION);  // set ADC bit resolution

  if (!setupSD()) return;

  // delete and create new file before each execution
  // remove this eventually
  SD.remove(filename);

  wavFile = SD.open(filename, FILE_WRITE); // create & name file
  writeWavHeader(); // write wav header
  wavFile.close(); // close file

  int prev_squelch = 0;  // store the previous squelch state

  while (1) {
    // read squelch state every loop
    int curr_squelch = digitalRead(squelch);

    // print squelch state
    Serial.print("curr squelch = ");
    Serial.println(curr_squelch);
    Serial.print("prev squelch = ");
    Serial.println(prev_squelch);

    // don't record if squelch goes from HIGH TO LOW
    if (prev_squelch == 1 && curr_squelch == 0) { continue; }

    // record audio if squelch breaks
    if (curr_squelch == 1) {
      wavFile = SD.open(filename, FILE_WRITE);
      if (wavFile) {
        writeDataToWavFile(getRecordData());
        wavFile.close();
      } 
      else {  // if the file didn't open, print an error
        Serial.print("recordSD(): error opening ");
        Serial.print(filename);
        Serial.println(".");
      }
      prev_squelch = 1;
    } 
    else {
      Serial.print("squelch not broken");
      //readSD(filename);
    }
  }
}

void loop() {}  // do nothing

问题: 如何获得我的 wav 文件的时间长度?是ADC有问题还是写入SD卡有问题?我也在考虑有一个缓冲区数组来存储数据,这有帮助吗?

c++ audio arduino wav arduino-c++
© www.soinside.com 2019 - 2024. All rights reserved.