2015-07-10 134 views
0

Matlab有一个叫做audioread的函数,我试图在C++中重现,但仅仅用于wav文件。我可以读取一个wav文件并从中获取double类型的值,但这些值似乎与Matlab函数返回的值不同。我的情况与this guy非常相似。我读文件代码:读取一个16位的wav文件,并将其规范化为Matlab

vector<double> rawAudioSignal; 

    std::basic_ifstream<uint8_t> inputStream(path.c_str(), std::ifstream::binary); 
    if (inputStream) { 
     // get length of file: 
     inputStream.seekg(0, inputStream.end); 
     int fileLength = inputStream.tellg(); 
     // go back to start of stream 
     inputStream.seekg(0, inputStream.beg); 

     uint8_t *buffer = new uint8_t[fileLength]; 
     inputStream.read((uint8_t *)buffer, fileLength); 
     inputStream.close(); 

     const int wavHeaderSize = 44; 
     for (size_t i = wavHeaderSize; i < fileLength; i += 2) 
     { 
      // removes those huge 65000+ value spikes 
      int c = ((char)buffer[i + 1]) << 8 | 
       ((unsigned char)buffer[i]); 

      // failed attempts 
      //int c = (buffer[i + 1] << 8 | buffer[i]); // little endian 
      //int c = (buffer[i] << 8 | buffer[i + 1]); // big endian 

      // failed normalizations 
      //rawAudioSignal.push_back((c/32768.0) - 1); 
      //rawAudioSignal.push_back(((c - 32768.0)/32768.0)); 
      rawAudioSignal.push_back(c); 
     } 
     delete[] buffer; 
    } 

所有rawAudioSignal值都约-5到5,但在Matlab整数,编号是从-1到1,其中该特定的最低值Matlab的文件是-0.2511,最高值是0.3846。我不知道Matlab函数是正常化的还是正常化的。任何帮助表示赞赏。

回答

3

样本是在-32768到32767范围内的16位,并且您希望它们缩放到-1.0到1.0。执行此操作的方法是除以32768.0(-32768/32768.0 == -1,32767/32768.0略小于1)。

你有从字节转换为int的正确的基本思想,所以我怀疑一些铸造可能会解决你的问题。在左移之前尝试将单个字节转换为int以防止可能的溢出。将其分解成多个语句并在调试器中观察它。

int c = ((int)buffer[i+1]) << 8 | buffer[i]; 
+0

我不知道为什么没有发生在我身上。我必须做的唯一改变如下:rawAudioSignal.push_back(c/32768.0);非常感谢您的帮助。 –

相关问题