Guest User

Untitled

a guest
Nov 7th, 2012
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.22 KB | None | 0 0
  1. bool AudioBuffer::readWAV(ResourceObject *obj)
  2. {
  3.    WAVChunkHdr chunkHdr;
  4.    WAVFmtExHdr fmtExHdr;
  5.    WAVFileHdr  fileHdr;
  6.    WAVSmplHdr  smplHdr;
  7.    WAVFmtHdr   fmtHdr;
  8.  
  9.    ALenum  format = AL_FORMAT_MONO16;
  10.    char   *data   = NULL;
  11.    ALsizei size   = 0;
  12.    ALsizei freq   = 22050;
  13.    ALboolean loop = AL_FALSE;
  14.  
  15.    Stream *stream = ResourceManager->openStream(obj);
  16.    if (!stream)
  17.       return false;
  18.  
  19.    stream->read(4, &fileHdr.id[0]);
  20.    stream->read(&fileHdr.size);
  21.    stream->read(4, &fileHdr.type[0]);
  22.  
  23.    fileHdr.size=((fileHdr.size+1)&~1)-4;
  24.  
  25.    stream->read(4, &chunkHdr.id[0]);
  26.    stream->read(&chunkHdr.size);
  27.    // unread chunk data rounded up to nearest WORD
  28.    S32 chunkRemaining = chunkHdr.size + (chunkHdr.size&1);
  29.  
  30.    while ((fileHdr.size!=0) && (stream->getStatus() != Stream::EOS))
  31.    {
  32.       // WAV Format header
  33.       if (!dStrncmp((const char*)chunkHdr.id,"fmt ",4))
  34.       {
  35.          stream->read(&fmtHdr.format);
  36.          stream->read(&fmtHdr.channels);
  37.          stream->read(&fmtHdr.samplesPerSec);
  38.          stream->read(&fmtHdr.bytesPerSec);
  39.          stream->read(&fmtHdr.blockAlign);
  40.          stream->read(&fmtHdr.bitsPerSample);
  41.  
  42.          if (fmtHdr.format==0x0001)
  43.          {
  44.             format=(fmtHdr.channels==1?
  45.                (fmtHdr.bitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16):
  46.                (fmtHdr.bitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16));
  47.             freq=fmtHdr.samplesPerSec;
  48.             chunkRemaining -= sizeof(WAVFmtHdr);
  49.          }
  50.          else
  51.          {
  52.             stream->read(sizeof(WAVFmtExHdr), &fmtExHdr);
  53.             chunkRemaining -= sizeof(WAVFmtExHdr);
  54.          }
  55.       }
  56.       // WAV Format header
  57.       else if (!dStrncmp((const char*)chunkHdr.id,"data",4))
  58.       {
  59.          if (fmtHdr.format==0x0001)
  60.          {
  61.             size=chunkHdr.size;
  62.             data=new char[chunkHdr.size];
  63.             if (data)
  64.             {
  65.                stream->read(chunkHdr.size, data);
  66. #if defined(TORQUE_OS_MAC)
  67.                // need to endian-flip the 16-bit data.
  68.                if (fmtHdr.bitsPerSample==16) // !!!TBD we don't handle stereo, so may be RL flipped.
  69.                {
  70.                   U16 *ds = (U16*)data;
  71.                   U16 *de = (U16*)(data+size);
  72.                   while (ds<de)
  73.                   {
  74. #if defined(TORQUE_BIG_ENDIAN)
  75.                      *ds = convertLEndianToHost(*ds);
  76. #else
  77.                      *ds = convertBEndianToHost(*ds);
  78. #endif
  79.                      ds++;
  80.                   }
  81.                }
  82. #endif
  83.                chunkRemaining -= chunkHdr.size;
  84.             }
  85.             else
  86.                break;
  87.          }
  88.          else if (fmtHdr.format==0x0011)
  89.          {
  90.             //IMA ADPCM
  91.          }
  92.          else if (fmtHdr.format==0x0055)
  93.          {
  94.             //MP3 WAVE
  95.          }
  96.       }
  97.       // WAV Loop header
  98.       else if (!dStrncmp((const char*)chunkHdr.id,"smpl",4))
  99.       {
  100.          // this struct read is NOT endian safe but it is ok because
  101.          // we are only testing the loops field against ZERO
  102.          stream->read(sizeof(WAVSmplHdr), &smplHdr);
  103.          loop = (smplHdr.loops ? AL_TRUE : AL_FALSE);
  104.          chunkRemaining -= sizeof(WAVSmplHdr);
  105.       }
  106.  
  107.       // either we have unread chunk data or we found an unknown chunk type
  108.       // loop and read up to 1K bytes at a time until we have
  109.       // read to the end of this chunk
  110.       char buffer[1024];
  111.       AssertFatal(chunkRemaining >= 0, "AudioBuffer::readWAV: remaining chunk data should never be less than zero.");
  112.       while (chunkRemaining > 0)
  113.       {
  114.          S32 readSize = getMin(1024, chunkRemaining);
  115.          stream->read(readSize, buffer);
  116.          chunkRemaining -= readSize;
  117.       }
  118.  
  119.       fileHdr.size-=(((chunkHdr.size+1)&~1)+8);
  120.  
  121.       // read next chunk header...
  122.       stream->read(4, &chunkHdr.id[0]);
  123.       stream->read(&chunkHdr.size);
  124.       // unread chunk data rounded up to nearest WORD
  125.       chunkRemaining = chunkHdr.size + (chunkHdr.size&1);
  126.    }
  127.  
  128.    ResourceManager->closeStream(stream);
  129.    if (data)
  130.    {
  131.       alBufferData(malBuffer, format, data, size, freq);
  132.       delete [] data;
  133.       return (alGetError() == AL_NO_ERROR);
  134.    }
  135.  
  136.    return false;
  137. }
Advertisement
Add Comment
Please, Sign In to add comment