Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OggStream.cpp
Go to the documentation of this file.
1 //
2 // C++ Implementation: Audio::OggStream
3 //
4 
5 #include "config.h"
6 
7 #ifdef HAVE_OGG
8 
9 #include "OggStream.h"
10 #include "OggData.h"
11 #include "config.h"
12 
13 #include <utility>
14 #include <limits>
15 
16 #include <vorbis/vorbisfile.h>
17 #include "vsfilesystem.h"
18 
19 #ifndef OGG_BUFFER_SIZE
20 #define OGG_BUFFER_SIZE 4096*2*2
21 #endif
22 
23 
24 namespace Audio {
25 
26  OggStream::OggStream(const std::string& path, VSFileSystem::VSFileType type) throw(Exception)
27  : Stream(path)
28  {
29  if ( file.OpenReadOnly(path, type) <= VSFileSystem::Ok )
30  throw FileOpenException("Error opening file \"" + path + "\"");
31  oggData = new __impl::OggData(file, getFormatInternal(), 0);
32 
33  // Cache duration in case ov_time_total gets expensive
34  duration = ov_time_total( &oggData->vorbisFile, oggData->streamIndex );
35 
36  // Allocate read buffer
37  readBufferSize = OGG_BUFFER_SIZE;
38  readBufferAvail = 0;
39  readBuffer = malloc(readBufferSize);
40  }
41 
42  OggStream::~OggStream()
43  {
44  // destructor closes the file already
45  delete oggData;
46  }
47 
48  double OggStream::getLengthImpl() const throw(Exception)
49  {
50  return duration;
51  }
52 
53  double OggStream::getPositionImpl() const throw()
54  {
55  return ov_time_tell( &oggData->vorbisFile );
56  }
57 
58  void OggStream::seekImpl(double position) throw(Exception)
59  {
60  if (position >= duration)
61  throw EndOfStreamException();
62 
63  readBufferAvail = 0;
64 
65  switch (ov_time_seek(&oggData->vorbisFile, position)) {
66  case 0: break;
67  case OV_ENOSEEK: throw Exception("Stream not seekable");
68  case OV_EINVAL: throw Exception("Invalid argument or state");
69  case OV_EREAD: throw Exception("Read error");
70  case OV_EFAULT: throw Exception("Internal logic fault, bug or heap/stack corruption");
71  case OV_EBADLINK:throw CorruptStreamException(false);
72  default: throw Exception("Unidentified error code");
73  }
74  }
75 
76  void OggStream::getBufferImpl(void *&buffer, unsigned int &bufferSize) throw(Exception)
77  {
78  if (readBufferAvail == 0)
79  throw NoBufferException();
80 
81  buffer = readBuffer;
82  bufferSize = readBufferAvail;
83  }
84 
85  void OggStream::nextBufferImpl() throw(Exception)
86  {
87  int curStream = oggData->streamIndex;
88  long ovr;
89  switch( ovr = ov_read(&oggData->vorbisFile,
90  (char*)readBuffer, readBufferSize,
91  0, 2, 1, &curStream) )
92  {
93  case OV_HOLE: throw CorruptStreamException(false);
94  case OV_EBADLINK: throw CorruptStreamException(false);
95  case 0: throw EndOfStreamException();
96  default: readBufferSize = ovr;
97  }
98  }
99 
100 
101 };
102 
103 #endif // HAVE_OGG
104