mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 22:56:40 +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))); }
 |