AudioBuffer.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. #include "Base.h"
  2. #include "AudioBuffer.h"
  3. #include "FileSystem.h"
  4. #ifdef __ANDROID__
  5. extern AAssetManager* __assetManager;
  6. #endif
  7. namespace gameplay
  8. {
  9. // Audio buffer cache
  10. static std::vector<AudioBuffer*> __buffers;
  11. #ifndef __ANDROID__
  12. AudioBuffer::AudioBuffer(const char* path, ALuint buffer)
  13. : _filePath(path), _alBuffer(buffer)
  14. {
  15. }
  16. #else
  17. AudioBuffer::AudioBuffer(const char* path) : _filePath(path)
  18. {
  19. }
  20. #endif
  21. AudioBuffer::~AudioBuffer()
  22. {
  23. #ifndef __ANDROID__
  24. if (_alBuffer)
  25. {
  26. alDeleteBuffers(1, &_alBuffer);
  27. _alBuffer = 0;
  28. }
  29. #endif
  30. }
  31. AudioBuffer* AudioBuffer::create(const char* path)
  32. {
  33. assert(path);
  34. // Search the cache for a stream from this file.
  35. unsigned int bufferCount = (unsigned int)__buffers.size();
  36. AudioBuffer* buffer = NULL;
  37. for (unsigned int i = 0; i < bufferCount; i++)
  38. {
  39. buffer = __buffers[i];
  40. if (buffer->_filePath.compare(path) == 0)
  41. {
  42. buffer->addRef();
  43. return buffer;
  44. }
  45. }
  46. #ifndef __ANDROID__
  47. ALuint alBuffer;
  48. ALCenum al_error;
  49. // Load audio data into a buffer.
  50. alGenBuffers(1, &alBuffer);
  51. al_error = alGetError();
  52. if (al_error != AL_NO_ERROR)
  53. {
  54. LOG_ERROR_VARG("AudioBuffer alGenBuffers AL error: %d", al_error);
  55. alDeleteBuffers(1, &alBuffer);
  56. return NULL;
  57. }
  58. // Load sound file.
  59. FILE* file = FileSystem::openFile(path, "rb");
  60. if (!file)
  61. {
  62. LOG_ERROR_VARG("Invalid audio buffer file: %s", path);
  63. goto cleanup;
  64. }
  65. // Read the file header
  66. char header[12];
  67. if (fread(header, 1, 12, file) != 12)
  68. {
  69. LOG_ERROR_VARG("Invalid audio buffer file: %s", path);
  70. goto cleanup;
  71. }
  72. // Check the file format
  73. if (memcmp(header, "RIFF", 4) == 0)
  74. {
  75. if (!AudioBuffer::loadWav(file, alBuffer))
  76. {
  77. LOG_ERROR_VARG("Invalid wave file: %s", path);
  78. goto cleanup;
  79. }
  80. }
  81. else if (memcmp(header, "OggS", 4) == 0)
  82. {
  83. if (!AudioBuffer::loadOgg(file, alBuffer))
  84. {
  85. LOG_ERROR_VARG("Invalid ogg file: %s", path);
  86. goto cleanup;
  87. }
  88. }
  89. else
  90. {
  91. LOG_ERROR_VARG("Unsupported audio file: %s", path);
  92. }
  93. fclose(file);
  94. buffer = new AudioBuffer(path, alBuffer);
  95. // Add the buffer to the cache.
  96. __buffers.push_back(buffer);
  97. return buffer;
  98. cleanup:
  99. if (file)
  100. fclose(file);
  101. if (alBuffer)
  102. alDeleteBuffers(1, &alBuffer);
  103. return NULL;
  104. #else
  105. // Get the file header in order to determine the type.
  106. AAsset* asset = AAssetManager_open(__assetManager, path, AASSET_MODE_RANDOM);
  107. char header[12];
  108. if (AAsset_read(asset, header, 12) != 12)
  109. {
  110. LOG_ERROR_VARG("Invalid audio buffer file: %s", path);
  111. return NULL;
  112. }
  113. // Get the file descriptor for the audio file.
  114. off_t start, length;
  115. int fd = AAsset_openFileDescriptor(asset, &start, &length);
  116. if (fd < 0)
  117. {
  118. LOG_ERROR_VARG("Failed to open file descriptor for asset: %s", path);
  119. return NULL;
  120. }
  121. AAsset_close(asset);
  122. SLDataLocator_AndroidFD data = {SL_DATALOCATOR_ANDROIDFD, fd, start, length};
  123. // Set the appropriate mime type information.
  124. SLDataFormat_MIME mime;
  125. mime.formatType = SL_DATAFORMAT_MIME;
  126. std::string pathStr = path;
  127. if (memcmp(header, "RIFF", 4) == 0)
  128. {
  129. mime.mimeType = (SLchar*)"audio/x-wav";
  130. mime.containerType = SL_CONTAINERTYPE_WAV;
  131. }
  132. else if (memcmp(header, "OggS", 4) == 0)
  133. {
  134. mime.mimeType = (SLchar*)"application/ogg";
  135. mime.containerType = SL_CONTAINERTYPE_OGG;
  136. }
  137. else
  138. {
  139. LOG_ERROR_VARG("Unsupported audio file: %s", path);
  140. }
  141. buffer = new AudioBuffer(path);
  142. buffer->_data = data;
  143. buffer->_mime = mime;
  144. // Add the buffer to the cache.
  145. __buffers.push_back(buffer);
  146. return buffer;
  147. #endif
  148. }
  149. #ifndef __ANDROID__
  150. bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
  151. {
  152. unsigned char stream[12];
  153. // Verify the wave fmt magic value meaning format.
  154. if (fread(stream, 1, 8, file) != 8 || memcmp(stream, "fmt ", 4) != 0 )
  155. return false;
  156. unsigned int section_size;
  157. section_size = stream[7]<<24;
  158. section_size |= stream[6]<<16;
  159. section_size |= stream[5]<<8;
  160. section_size |= stream[4];
  161. // Check for a valid pcm format.
  162. if (fread(stream, 1, 2, file) != 2 || stream[1] != 0 || stream[0] != 1)
  163. {
  164. LOG_ERROR("Unsupported audio file, not PCM format.");
  165. return false;
  166. }
  167. // Get the channel count (16-bit little-endian)
  168. int channels;
  169. if (fread(stream, 1, 2, file) != 2)
  170. return false;
  171. channels = stream[1]<<8;
  172. channels |= stream[0];
  173. // Get the sample frequency (32-bit little-endian)
  174. ALuint frequency;
  175. if (fread(stream, 1, 4, file) != 4)
  176. return false;
  177. frequency = stream[3]<<24;
  178. frequency |= stream[2]<<16;
  179. frequency |= stream[1]<<8;
  180. frequency |= stream[0];
  181. // The next 6 bytes hold the block size and bytes-per-second.
  182. // We don't need that info, so just read and ignore it.
  183. // We could use this later if we need to know the duration.
  184. if (fread(stream, 1, 6, file) != 6)
  185. return false;
  186. // Get the bit depth (16-bit little-endian)
  187. int bits;
  188. if (fread(stream, 1, 2, file) != 2)
  189. return false;
  190. bits = stream[1]<<8;
  191. bits |= stream[0];
  192. // Now convert the given channel count and bit depth into an OpenAL format.
  193. ALuint format = 0;
  194. if (bits == 8)
  195. {
  196. if (channels == 1)
  197. format = AL_FORMAT_MONO8;
  198. else if (channels == 2)
  199. format = AL_FORMAT_STEREO8;
  200. }
  201. else if (bits == 16)
  202. {
  203. if (channels == 1)
  204. format = AL_FORMAT_MONO16;
  205. else if (channels == 2)
  206. format = AL_FORMAT_STEREO16;
  207. }
  208. else
  209. {
  210. LOG_ERROR_VARG("Incompatible format: (%d, %d)", channels, bits);
  211. return false;
  212. }
  213. // Check against the size of the format header as there may be more data that we need to read
  214. if (section_size > 16)
  215. {
  216. unsigned int length = section_size - 16;
  217. // extension size is 2 bytes
  218. if (fread(stream, 1, length, file) != length)
  219. return false;
  220. }
  221. if (fread(stream, 1, 4, file) != 4)
  222. return false;
  223. // read the next chunk, could be fact section or the data section
  224. if (memcmp(stream, "fact", 4) == 0)
  225. {
  226. if (fread(stream, 1, 4, file) != 4)
  227. return false;
  228. section_size = stream[3]<<24;
  229. section_size |= stream[2]<<16;
  230. section_size |= stream[1]<<8;
  231. section_size |= stream[0];
  232. // read in the rest of the fact section
  233. if (fread(stream, 1, section_size, file) != section_size)
  234. return false;
  235. if (fread(stream, 1, 4, file) != 4)
  236. return false;
  237. }
  238. // should now be the data section which holds the decoded sample data
  239. if (memcmp(stream, "data", 4) != 0)
  240. {
  241. LOG_ERROR("WAV file has no data.");
  242. return false;
  243. }
  244. // Read how much data is remaining and buffer it up.
  245. unsigned int dataSize;
  246. fread(&dataSize, sizeof(int), 1, file);
  247. char* data = new char[dataSize];
  248. if (fread(data, sizeof(char), dataSize, file) != dataSize)
  249. {
  250. LOG_ERROR("WAV file missing data.");
  251. SAFE_DELETE_ARRAY(data);
  252. return false;
  253. }
  254. alBufferData(buffer, format, data, dataSize, frequency);
  255. SAFE_DELETE_ARRAY(data);
  256. return true;
  257. }
  258. bool AudioBuffer::loadOgg(FILE* file, ALuint buffer)
  259. {
  260. OggVorbis_File ogg_file;
  261. vorbis_info* info;
  262. ALenum format;
  263. int result;
  264. int section;
  265. unsigned int size = 0;
  266. rewind(file);
  267. if ((result = ov_open(file, &ogg_file, NULL, 0)) < 0)
  268. {
  269. fclose(file);
  270. LOG_ERROR("Could not open Ogg stream.");
  271. return false;
  272. }
  273. info = ov_info(&ogg_file, -1);
  274. if (info->channels == 1)
  275. format = AL_FORMAT_MONO16;
  276. else
  277. format = AL_FORMAT_STEREO16;
  278. // size = #samples * #channels * 2 (for 16 bit)
  279. unsigned int data_size = ov_pcm_total(&ogg_file, -1) * info->channels * 2;
  280. char* data = new char[data_size];
  281. while (size < data_size)
  282. {
  283. result = ov_read(&ogg_file, data + size, data_size - size, 0, 2, 1, &section);
  284. if (result > 0)
  285. {
  286. size += result;
  287. }
  288. else if (result < 0)
  289. {
  290. SAFE_DELETE_ARRAY(data);
  291. LOG_ERROR("OGG file missing data.");
  292. return false;
  293. }
  294. else
  295. {
  296. break;
  297. }
  298. }
  299. if (size == 0)
  300. {
  301. SAFE_DELETE_ARRAY(data);
  302. LOG_ERROR("Unable to read OGG data.");
  303. return false;
  304. }
  305. alBufferData(buffer, format, data, data_size, info->rate);
  306. SAFE_DELETE_ARRAY(data);
  307. ov_clear(&ogg_file);
  308. // ov_clear actually closes the file pointer as well
  309. file = 0;
  310. return true;
  311. }
  312. #endif
  313. }