Demofox

Huggins Binaural Pitch Failure

Jun 25th, 2016
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.42 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <memory.h>
  3. #include <inttypes.h>
  4. #include <vector>
  5.  
  6. // constants
  7. const float c_pi = 3.14159265359f;
  8. const float c_twoPi = 2.0f * c_pi;
  9.  
  10. // typedefs
  11. typedef uint16_t    uint16;
  12. typedef uint32_t    uint32;
  13. typedef int16_t     int16;
  14. typedef int32_t     int32;
  15.  
  16. //this struct is the minimal required header data for a wav file
  17. struct SMinimalWaveFileHeader
  18. {
  19.     //the main chunk
  20.     unsigned char m_chunkID[4];
  21.     uint32        m_chunkSize;
  22.     unsigned char m_format[4];
  23.  
  24.     //sub chunk 1 "fmt "
  25.     unsigned char m_subChunk1ID[4];
  26.     uint32        m_subChunk1Size;
  27.     uint16        m_audioFormat;
  28.     uint16        m_numChannels;
  29.     uint32        m_sampleRate;
  30.     uint32        m_byteRate;
  31.     uint16        m_blockAlign;
  32.     uint16        m_bitsPerSample;
  33.  
  34.     //sub chunk 2 "data"
  35.     unsigned char m_subChunk2ID[4];
  36.     uint32        m_subChunk2Size;
  37.  
  38.     //then comes the data!
  39. };
  40.  
  41. //this writes
  42. template <typename T>
  43. bool WriteWaveFile(const char *fileName, std::vector<T> data, int16 numChannels, int32 sampleRate)
  44. {
  45.     int32 dataSize = data.size() * sizeof(T);
  46.     int32 bitsPerSample = sizeof(T) * 8;
  47.  
  48.     //open the file if we can
  49.     FILE *File = nullptr;
  50.     fopen_s(&File, fileName, "w+b");
  51.     if (!File)
  52.         return false;
  53.  
  54.     SMinimalWaveFileHeader waveHeader;
  55.  
  56.     //fill out the main chunk
  57.     memcpy(waveHeader.m_chunkID, "RIFF", 4);
  58.     waveHeader.m_chunkSize = dataSize + 36;
  59.     memcpy(waveHeader.m_format, "WAVE", 4);
  60.  
  61.     //fill out sub chunk 1 "fmt "
  62.     memcpy(waveHeader.m_subChunk1ID, "fmt ", 4);
  63.     waveHeader.m_subChunk1Size = 16;
  64.     waveHeader.m_audioFormat = 1;
  65.     waveHeader.m_numChannels = numChannels;
  66.     waveHeader.m_sampleRate = sampleRate;
  67.     waveHeader.m_byteRate = sampleRate * numChannels * bitsPerSample / 8;
  68.     waveHeader.m_blockAlign = numChannels * bitsPerSample / 8;
  69.     waveHeader.m_bitsPerSample = bitsPerSample;
  70.  
  71.     //fill out sub chunk 2 "data"
  72.     memcpy(waveHeader.m_subChunk2ID, "data", 4);
  73.     waveHeader.m_subChunk2Size = dataSize;
  74.  
  75.     //write the header
  76.     fwrite(&waveHeader, sizeof(SMinimalWaveFileHeader), 1, File);
  77.  
  78.     //write the wave data itself
  79.     fwrite(&data[0], dataSize, 1, File);
  80.  
  81.     //close the file and return success
  82.     fclose(File);
  83.     return true;
  84. }
  85.  
  86. template <typename T>
  87. void ConvertFloatSamples (const std::vector<float>& in, std::vector<T>& out)
  88. {
  89.     // make our out samples the right size
  90.     out.resize(in.size());
  91.  
  92.     // convert in format to out format !
  93.     for (size_t i = 0, c = in.size(); i < c; ++i)
  94.     {
  95.         float v = in[i];
  96.         if (v < 0.0f)
  97.             v *= -float(std::numeric_limits<T>::lowest());
  98.         else
  99.             v *= float(std::numeric_limits<T>::max());
  100.         out[i] = T(v);
  101.     }
  102. }
  103.  
  104. void GenerateSamples (std::vector<float>& samples, int sampleRate)
  105. {
  106.     // make mono noise samples
  107.     std::vector<float> noise;
  108.     noise.resize(samples.size() / 2);
  109.     for (float &v : noise)
  110.         v = ((float)rand()) / ((float)RAND_MAX) * 2.0f - 1.0f;
  111.  
  112.     // calculate some constants
  113.     const int sectionLength = noise.size() / 2;
  114.  
  115.     // how much shift
  116.     float frequency = 200.0f;
  117.     int shift = int(float(sampleRate) / frequency);
  118.  
  119.     // generate samples
  120.     for (int index = 0, numSamples = noise.size(); index < numSamples; ++index)
  121.     {
  122.         int section = index / sectionLength;
  123.         int offset = section > 0 ? shift : 0;
  124.  
  125.         float left = noise[index];
  126.         float right = noise[(index + offset) % numSamples];
  127.        
  128.         samples[index * 2] = left;
  129.         samples[index * 2 + 1] = right;
  130.     }
  131. }
  132.  
  133. //the entry point of our application
  134. int main(int argc, char **argv)
  135. {
  136.     // generate the stereo whitenoise offset effect
  137.     {
  138.         // sound format parameters
  139.         const int c_sampleRate = 44100;
  140.         const int c_numSeconds = 2;
  141.         const int c_numChannels = 2;
  142.         const int c_numSamples = c_sampleRate * c_numChannels * c_numSeconds;
  143.  
  144.         // make space for our samples
  145.         std::vector<float> samples;
  146.         samples.resize(c_numSamples);
  147.  
  148.         // generate samples
  149.         GenerateSamples(samples, c_sampleRate);
  150.  
  151.         // convert from float to the final format
  152.         std::vector<int32> samplesInt;
  153.         ConvertFloatSamples(samples, samplesInt);
  154.  
  155.         // write our samples to a wave file
  156.         WriteWaveFile("stereonoise.wav", samplesInt, c_numChannels, c_sampleRate);
  157.     }
  158. }
Add Comment
Please, Sign In to add comment