C++阅读FIR滤波器的WAV数据

3xiyfsfu  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(188)

我试图从FIR滤波器的WAV文件中获取数据。这就是我到目前为止所做的。这个代码是否正确阅读WAV?此外,我需要存储数据到一个双数组,以便能够将它们传递到FIR滤波器函数以后。我不知道该怎么做。
编辑:在阅读了一些有关WAV文件的更多信息后,我现在改变了我的代码。现在看起来好些了吗?如何将缺少数据的数组转换为双精度数组?

  1. struct wav_header_t
  2. {
  3. char chunkID[4]; //"RIFF"
  4. unsigned long chunkSize;
  5. char format[4]; //"WAVE"
  6. char subchunk1ID[4]; //"fmt "
  7. unsigned long subchunk1Size; //16
  8. unsigned short audioFormat;
  9. unsigned short numChannels;
  10. unsigned long sampleRate;
  11. unsigned long byteRate;
  12. unsigned short blockAlign;
  13. unsigned short bitsPerSample;
  14. };
  15. //Chunks
  16. struct chunk_t
  17. {
  18. char ID[4]; //"data"
  19. unsigned long size; //Chunk data bytes
  20. };
  21. void WAV::vRead()
  22. {
  23. //open file
  24. cout << sName <<" will be open"<<endl;
  25. FILE* handle;
  26. fopen_s(&handle, sName, "rb");
  27. if (handle == NULL)
  28. {
  29. cout << "file opened unsuccessfully" << endl;
  30. return;
  31. }
  32. else
  33. {
  34. cout << sName << " is open" << endl;
  35. }
  36. //size of file.wav
  37. fseek(handle, 0, SEEK_END);
  38. long fileSize = ftell(handle);
  39. //read wav-Headers
  40. wav_header_t header;
  41. fread(&header, sizeof(header), 1, handle);
  42. //Reading file
  43. chunk_t chunk;
  44. //go to data chunk
  45. while (true)
  46. {
  47. fread(&chunk, sizeof(chunk), 1, handle);
  48. if (*(unsigned int*)&chunk.ID == 0x61746164)
  49. break;
  50. //skip chunk data bytes
  51. fseek(handle, chunk.size, SEEK_CUR);
  52. }
  53. //Number of samples
  54. int sample_size = header.bitsPerSample / 8;
  55. int samples_count = chunk.size * 8 / header.bitsPerSample;
  56. short int* value = new short int[samples_count];
  57. memset(value, 0, sizeof(short int) * samples_count);
  58. //Reading data
  59. for (int i = 0; i < samples_count; i++)
  60. {
  61. fread(&value[i], sample_size, 1, handle);
  62. }
  63. fclose(handle);
  64. return;
  65. }
u7up0aaq

u7up0aaq1#

您在评论中缺少的和要求的是从16位整数转换为双精度。
下面是一个将交织的16位整数转换为归一化双精度的示例。假设是2声道立体声。根据需要进行调整。

  1. #include <vector>
  2. #include <algorithm>
  3. #include <array>
  4. #include <iostream>
  5. std::vector<std::array<double,2>> get_normalized_wav_doubles(const std::vector<int16_t> wav)
  6. {
  7. std::vector<std::array<double, 2>> ret(wav.size() / 2);
  8. for (size_t i = 0; i < wav.size(); i+=2)
  9. {
  10. ret[i / 2][0] = wav[i] / 32768.0; // normalized doubles to +-1
  11. ret[i / 2][1] = wav[i+1] / 32768.0;
  12. }
  13. return ret;
  14. }
  15. int main()
  16. {
  17. std::vector<int16_t> wav{10, -20, 30, -40, 50, -60}; // 6 16 bit ints interleaved for stereo
  18. std::vector<std::array<double, 2>> f_set = get_normalized_wav_doubles(wav);
  19. for (const auto& x : f_set)
  20. {
  21. std::cout << x[0] << "\n"; // first channel
  22. std::cout << x[1] << "\n\n"; // second channel
  23. }
  24. }

输出:

  1. 0.000305176
  2. -0.000610352
  3. 0.000915527
  4. -0.0012207
  5. 0.00152588
  6. -0.00183105
展开查看全部

相关问题