TDME2  1.9.200
VorbisDecoder.cpp
Go to the documentation of this file.
1 // This source code is based on
2 /********************************************************************
3  * *
4  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
5  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
6  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
7  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8  * *
9  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
10  * by the Xiph.Org Foundation http://www.xiph.org/ *
11  * *
12  ********************************************************************/
13 
14 #include <stdio.h>
15 
17 
18 #include <vorbis/vorbisfile.h>
19 
20 #include <string>
21 #include <memory>
22 
23 #include <tdme/tdme.h>
31 
32 using std::make_unique;
33 using std::string;
34 using std::vector;
35 
42 
43 size_t VorbisDecoder::oggfiledata_read(void* buffer, size_t size, size_t count, VorbisDecoder::OGGFileData* oggFileData) {
44  size_t bytesRead = 0;
45  for (size_t i = 0; i < size * count; i++) {
46  if (oggFileData->position == oggFileData->data.size()) break;
47  ((uint8_t*)buffer)[i] = oggFileData->data[oggFileData->position];
48  bytesRead++;
49  oggFileData->position++;
50  }
51  return bytesRead;
52 }
53 
54 int VorbisDecoder::oggfiledata_seek(VorbisDecoder::OGGFileData* oggFileData, ogg_int64_t offset, int whence) {
55  switch (whence) {
56  case SEEK_SET:
57  oggFileData->position = offset;
58  return 0;
59  case SEEK_CUR:
60  oggFileData->position+= offset;
61  return 0;
62  case SEEK_END:
63  oggFileData->position = oggFileData->data.size() + offset;
64  return 0;
65  default:
66  return 1;
67  }
68 }
69 
71  return 0;
72 }
73 
75  return oggFileData->position;
76 }
77 
78 void VorbisDecoder::openFile(const string& pathName, const string& fileName) {
79  // read from file system
80  oggFileData = make_unique<OGGFileData>();
81  FileSystem::getInstance()->getContent(pathName, fileName, oggFileData->data);
82  if (oggFileData->data.size() == 0) {
83  throw AudioDecoderException("No input");
84  }
85 
86  // set up ogg file callbacks
87  static ov_callbacks oggFileCallbacks = {
88  (size_t (*)(void *, size_t, size_t, void *)) oggfiledata_read,
89  (int (*)(void *, ogg_int64_t, int)) oggfiledata_seek,
90  (int (*)(void *)) oggfiledata_close,
91  (long (*)(void *)) oggfiledata_tell
92  };
93 
94  //
95  this->pathName = pathName;
96  this->fileName = fileName;
97  if (ov_open_callbacks(oggFileData.get(), &vf, NULL, 0, oggFileCallbacks) < 0) {
98  throw AudioDecoderException("Input does not appear to be an OGG bitstream");
99  }
100 
101  // vorbis info
102  vorbis_info *vi = ov_info(&vf, -1);
103 
104  /*
105  // fetch audio stream properties
106  char **ptr = ov_comment(&vf, -1)->user_comments;
107  // Throw the comments plus a few lines about the bitstream we're decoding
108  while (*ptr) {
109  fprintf(stderr, "%s\n", *ptr);
110  ++ptr;
111  }
112  fprintf(stderr, "\nBitstream is %d channel, %ldHz\n", vi->channels, vi->rate);
113  fprintf(stderr, "\nDecoded length: %ld samples\n",(long) ov_pcm_total(&vf, -1));
114  fprintf(stderr, "Encoded by: %s\n\n", ov_comment(&vf, -1)->vendor);
115  */
116 
117  // set audio stream properties
118  channels = vi->channels;
119  sampleRate = vi->rate;
120  bitsPerSample = 16;
121  samples = ov_pcm_total(&vf, -1);
122  section = 0;
123 }
124 
126  close();
128 }
129 
131  auto read = 0LL;
132  while (read < data->getCapacity()) {
133  long len = ov_read(
134  &vf,
135  (char*)(data->getBuffer() + read),
136  data->getCapacity() - read,
137  // powerpc and powerpc64 are considered to use big endianess for now
138  #if defined(__powerpc__) || defined(__powerpc64__)
139  1,
140  #else
141  0,
142  #endif
143  2,
144  1,
145  &section
146  );
147  if (len <= 0) break;
148  read+= len;
149  }
150  data->setPosition(read);
151  return read;
152 }
153 
155  if (oggFileData == nullptr) return;
156  if (oggFileData->data.size() > 0) ov_clear(&vf);
157  oggFileData = nullptr;
158 }
OGG/Vorbis audio decoder.
Definition: VorbisDecoder.h:31
static int oggfiledata_close(VorbisDecoder::OGGFileData *oggFileData)
Close OGG file data.
static int oggfiledata_seek(VorbisDecoder::OGGFileData *oggFileData, ogg_int64_t offset, int whence)
Seek in OGG file data.
unique_ptr< OGGFileData > oggFileData
Definition: VorbisDecoder.h:89
void close() override
Closes the audio file.
int64_t readFromStream(ByteBuffer *data) override
Read raw PCM data from stream.
static size_t oggfiledata_read(void *buffer, size_t size, size_t count, VorbisDecoder::OGGFileData *oggFileData)
Read from OGG file data.
void reset() override
Resets this audio decoder, if a stream was open it will be rewinded.
void openFile(const string &pathName, const string &fileName) override
Open a local file.
static long oggfiledata_tell(VorbisDecoder::OGGFileData *oggFileData)
Tell position of OGG file data.
File system singleton class.
Definition: FileSystem.h:17
virtual Buffer * setPosition(int64_t position)
Set position.
Definition: Buffer.h:98
const uint8_t * getBuffer() const
Definition: Buffer.h:150
virtual int64_t getCapacity() const
Definition: Buffer.h:82
Byte buffer class.
Definition: ByteBuffer.h:27