mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 15:26:57 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			99 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "wav_source.hpp"
 | 
						|
 | 
						|
#include "../../stream/servers/file_stream.hpp"
 | 
						|
 | 
						|
#include <stdexcept>
 | 
						|
 | 
						|
using namespace Mangle::Stream;
 | 
						|
using namespace Mangle::Sound;
 | 
						|
 | 
						|
static void fail(const std::string &msg)
 | 
						|
{ throw std::runtime_error("Mangle::Wav exception: " + msg); }
 | 
						|
 | 
						|
void WavSource::getInfo(int32_t *pRate, int32_t *pChannels, int32_t *pBits)
 | 
						|
{
 | 
						|
  // Use the values we found in the constructor
 | 
						|
  *pRate = rate;
 | 
						|
  *pChannels = channels;
 | 
						|
  *pBits = bits;
 | 
						|
}
 | 
						|
 | 
						|
void WavSource::seek(size_t pos)
 | 
						|
{
 | 
						|
  // Seek the stream and set 'left'
 | 
						|
  assert(isSeekable);
 | 
						|
  if(pos > total) pos = total;
 | 
						|
  input->seek(dataOffset + pos);
 | 
						|
  left = total-pos;
 | 
						|
}
 | 
						|
 | 
						|
size_t WavSource::read(void *data, size_t length)
 | 
						|
{
 | 
						|
  if(length > left)
 | 
						|
    length = left;
 | 
						|
  size_t read = input->read(data, length);
 | 
						|
  if(read < length)
 | 
						|
    // Something went wrong
 | 
						|
    fail("WAV read error");
 | 
						|
  return length;
 | 
						|
}
 | 
						|
 | 
						|
void WavSource::open(Mangle::Stream::StreamPtr data)
 | 
						|
{
 | 
						|
  input = data;
 | 
						|
 | 
						|
  hasPosition = true;
 | 
						|
  hasSize = true;
 | 
						|
  // If we can check position and seek in the input stream, then we
 | 
						|
  // can seek the wav data too.
 | 
						|
  isSeekable = input->isSeekable && input->hasPosition;
 | 
						|
 | 
						|
  // Read header
 | 
						|
  unsigned int val;
 | 
						|
 | 
						|
  input->read(&val,4);  // header
 | 
						|
  if(val != 0x46464952) // "RIFF"
 | 
						|
    fail("Not a WAV file");
 | 
						|
 | 
						|
  input->read(&val,4);  // size (ignored)
 | 
						|
  input->read(&val,4);  // file format
 | 
						|
  if(val != 0x45564157) // "WAVE"
 | 
						|
    fail("Not a valid WAV file");
 | 
						|
 | 
						|
  input->read(&val,4);  // "fmt "
 | 
						|
  input->read(&val,4);  // chunk size (must be 16)
 | 
						|
  if(val != 16)
 | 
						|
    fail("Unsupported WAV format");
 | 
						|
 | 
						|
  input->read(&val,2);
 | 
						|
  if(val != 1)
 | 
						|
    fail("Non-PCM (compressed) WAV files not supported");
 | 
						|
 | 
						|
  // Sound data specification
 | 
						|
  channels = 0;
 | 
						|
  input->read(&channels,2);
 | 
						|
  input->read(&rate, 4);
 | 
						|
 | 
						|
  // Skip next 6 bytes
 | 
						|
  input->read(&val, 4);
 | 
						|
  input->read(&val, 2);
 | 
						|
 | 
						|
  // Bits per sample
 | 
						|
  bits = 0;
 | 
						|
  input->read(&bits,2);
 | 
						|
 | 
						|
  input->read(&val,4);  // Data header
 | 
						|
  if(val != 0x61746164) // "data"
 | 
						|
    fail("Expected data block");
 | 
						|
 | 
						|
  // Finally, read the data size
 | 
						|
  input->read(&total,4);
 | 
						|
  left = total;
 | 
						|
 | 
						|
  // Store the beginning of the data block for later
 | 
						|
  if(input->hasPosition)
 | 
						|
    dataOffset = input->tell();
 | 
						|
}
 | 
						|
 | 
						|
WavSource::WavSource(const std::string &file)
 | 
						|
{ open(StreamPtr(new FileStream(file))); }
 |