AudioBuffer.cpp 9.6 KB

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