zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Sound_Buffer.cpp
Go to the documentation of this file.
1 /* This file is part of the Zenipex Library (zenilib).
2  * Copyright (C) 2011 Mitchell Keith Bloch (bazald).
3  *
4  * zenilib is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * zenilib is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with zenilib. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <zeni_audio.h>
19 
20 #include <iostream>
21 #include <vector>
22 #include <iomanip>
23 
24 #ifndef DISABLE_AL
25 #define OV_EXCLUDE_STATIC_CALLBACKS
26 #include <vorbis/vorbisfile.h>
27 #undef OV_EXCLUDE_STATIC_CALLBACKS
28 #endif
29 
30 #if defined(_DEBUG) && defined(_WINDOWS)
31 #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
32 #define new DEBUG_NEW
33 #endif
34 
35 namespace Zeni {
36 
37  Sound_Buffer::Sound_Buffer()
38  :
39 #ifndef DISABLE_AL
40  m_buffer(AL_NONE),
41 #endif
42  m_duration(float())
43  //, m_loader(0)
44  //, m_thread(0)
45  {
46  Sound &sr = get_Sound();
47 
48  const String &filename = "sfx/104469__dkmedic__world";
49 
50 #ifndef DISABLE_AL
51  if(dynamic_cast<Sound_Renderer_AL *>(&sr.get_Renderer())) {
52  //m_loader = new Loader(filename);
53  //m_thread = new Thread(*m_loader);
54 
55  std::pair<ALuint, float> loaded_ogg = load_ogg_vorbis(filename);
56 
57  if(loaded_ogg.first == AL_NONE) {
58  std::cerr << "OpenAL error on '" << filename << "': " << Sound_Renderer_AL::errorString() << std::endl;
59  throw Sound_Buffer_Init_Failure();
60  }
61 
62  m_buffer = loaded_ogg.first;
63  m_duration = loaded_ogg.second;
64  }
65 #endif
66 #ifdef ENABLE_SLES
67  init_SLES(filename);
68 #endif
69  }
70 
71  Sound_Buffer::Sound_Buffer(const String &filename)
72  :
73 #ifndef DISABLE_AL
74  m_buffer(AL_NONE),
75 #endif
76  m_duration(float())
77  //, m_loader(0)
78  //, m_thread(0)
79  {
80  Sound &sr = get_Sound();
81 
82 #ifndef DISABLE_AL
83  if(dynamic_cast<Sound_Renderer_AL *>(&sr.get_Renderer())) {
84  //m_loader = new Loader(filename);
85  //m_thread = new Thread(*m_loader);
86 
87  std::pair<ALuint, float> loaded_ogg = load_ogg_vorbis(filename);
88 
89  if(loaded_ogg.first == AL_NONE) {
90  std::cerr << "OpenAL error on '" << filename << "': " << Sound_Renderer_AL::errorString() << std::endl;
91  throw Sound_Buffer_Init_Failure();
92  }
93 
94  m_buffer = loaded_ogg.first;
95  m_duration = loaded_ogg.second;
96  }
97 #endif
98 #ifdef ENABLE_SLES
99  init_SLES(filename);
100 #endif
101  }
102 
103  Sound_Buffer::~Sound_Buffer() {
104  //delete m_thread;
105  //delete m_loader;
106 
107 #ifndef DISABLE_AL
108  if(m_buffer != AL_NONE && !Quit_Event::has_fired())
109  Sound_Renderer_AL::alDeleteBuffers()(1, &m_buffer);
110 #endif
111  }
112 
113  std::pair<ALuint, float> Sound_Buffer::load_ogg_vorbis(const String &
114 #ifndef DISABLE_AL
115  filename
116 #endif
117  ) {
118 
119 #ifndef DISABLE_AL
120  /*** Open VorbisFile ***/
121 
122  OggVorbis_File oggFile;
123  if(ov_fopen(const_cast<char *>((filename + ".ogg").c_str()), &oggFile))
124  return std::make_pair(AL_NONE, 0.0f);
125 
126  /*** Get Information About the Audio File ***/
127 
128  vorbis_info *pInfo = ov_info(&oggFile, -1);
129  const ALenum format = pInfo->channels == 2 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
130  const ALsizei freq = ALsizei(pInfo->rate);
131  const ALsizei bytes_per_sample = format == AL_FORMAT_STEREO16 ? 4 : 2;
132  const ogg_int64_t num_samples = ov_pcm_total(&oggFile, -1);
133  const ogg_int64_t pcm_size = num_samples * bytes_per_sample;
134  const float duration = float(num_samples) / freq;
135 
136 #ifndef NDEBUG
137  if(format == AL_FORMAT_STEREO16)
138  std::cerr << "WARNING: '" << filename << "' is stereo and will be unaffected by the OpenAL positional audio system." << std::endl;
139 #endif
140 
141  /*** Load the Audio File ***/
142 
143  int bytes = 0;
144  int buffer_size = int(pcm_size);
145  std::vector<char> buffer( static_cast<size_t>(buffer_size) );
146  for(char *begin = &buffer[0], *end = begin + pcm_size;
147  begin != end;
148  begin += bytes, buffer_size -= bytes) {
149  bytes = int(ov_read(&oggFile, begin, buffer_size, 0, 2, 1, 0));
150 
151  if(!bytes) {
152  ov_clear(&oggFile);
154  }
155  }
156 
157  /*** Generate Audio Buffer ***/
158 
159  ALuint bufferID = AL_NONE;
160  Sound_Renderer_AL::alGenBuffers()(1, &bufferID);
161  Sound_Renderer_AL::alBufferData()(bufferID, format, &buffer[0], static_cast<ALsizei>(buffer.size()), freq);
162 
163  return std::make_pair(bufferID, duration);
164 
165 #else
166 
167  return std::make_pair(AL_NONE, 0.0f);
168 
169 #endif
170 
171  }
172 
173 #ifdef ENABLE_SLES
174  void Sound_Buffer::init_SLES(const String &filename) {
175  if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) {
176  // use asset manager to open asset by filename
177  AAsset* asset = AAssetManager_open(File_Ops::get_AAssetManager(), (filename + ".wav").c_str(), AASSET_MODE_UNKNOWN);
178  if(!asset)
180 
181  // open asset as file descriptor
182  off_t start, length;
183  int fd = AAsset_openFileDescriptor(asset, &start, &length);
184  assert(0 <= fd);
185  AAsset_close(asset);
186 
187  // configure audio source
188  loc_fd = {SL_DATALOCATOR_ANDROIDFD, fd, start, length};
189  format_mime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
190  audioSrc = {&loc_fd, &format_mime};
191  }
192  }
193 #endif
194 
195 // Sound_Buffer::Loader::Loader(const String &filename)
196 // : m_duration(0.0f),
197 // m_filename(filename)
198 // {
199 // }
200 //
201 // int Sound_Buffer::Loader::function() {
202 //#ifndef DISABLE_AL
203 // std::pair<ALuint, float> loaded_ogg = load_ogg_vorbis(m_filename);
204 //
205 // if(loaded_ogg.first == AL_NONE) {
206 // std::cerr << "OpenAL error on '" << m_filename << "': " << Sound_Renderer_AL::errorString() << std::endl;
207 // return -1;
208 // }
209 //
210 // m_buffer = loaded_ogg.first;
211 // m_duration = loaded_ogg.second;
212 //#endif
213 //
214 // return 0;
215 // }
216 //
217 // void Sound_Buffer::finish_loading() const {
218 // delete m_thread;
219 // m_thread = 0;
220 //
221 // const int status = m_loader->status;
222 // m_buffer = m_loader->m_buffer;
223 // m_duration = m_loader->m_duration;
224 //
225 // delete m_loader;
226 // m_loader = 0;
227 //
228 // if(status)
229 // throw Sound_Buffer_Init_Failure();
230 // }
231 
232 }
#define AL_NONE
Definition: al.h:80
#define NULL
Definition: ftobjs.h:61
GLuint start
Definition: glew.h:1239
GLclampf f
Definition: glew.h:3390
int ALsizei
Definition: al.h:62
int ov_clear(OggVorbis_File *vf)
Definition: vorbisfile.c:955
#define assert(x)
Definition: SDL_malloc.c:1234
int ov_fopen(const char *path, OggVorbis_File *vf)
Definition: vorbisfile.c:1011
ogg_int64_t ov_pcm_total(OggVorbis_File *vf, int i)
Definition: vorbisfile.c:1189
static std::pair< ALuint, float > load_ogg_vorbis(const String &filename)
Ogg Vorbis Loader.
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
int channels
Definition: codec.h:30
Sound & get_Sound()
Get access to the singleton.
Definition: Sound.cpp:220
int
Definition: SDL_systhread.c:37
GLsizei GLsizei * length
Definition: gl2ext.h:792
vorbis_info * ov_info(OggVorbis_File *vf, int link)
Definition: vorbisfile.c:1791
static alBufferData_fcn alBufferData()
int ALenum
Definition: al.h:65
#define AL_FORMAT_MONO16
Definition: al.h:340
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
unsigned int ALuint
Definition: al.h:59
long ov_read(OggVorbis_File *vf, char *buffer, int length, int bigendianp, int word, int sgned, int *bitstream)
Definition: vorbisfile.c:2007
static alDeleteBuffers_fcn alDeleteBuffers()
static bool has_fired()
Definition: Quit_Event.h:41
long rate
Definition: codec.h:31
#define AL_FORMAT_STEREO16
Definition: al.h:342
GLuint GLuint end
Definition: glew.h:1239
long ogg_int64_t
Definition: config_types.h:23
static alGenBuffers_fcn alGenBuffers()