Advertisement
Guest User

Use Cache for Sounds

a guest
Oct 30th, 2021
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.75 KB | None | 0 0
  1. /* bzflag
  2. * Copyright (c) 1993-2021 Tim Riker
  3. *
  4. * This package is free software; you can redistribute it and/or
  5. * modify it under the terms of the license found in the file
  6. * named COPYING that should have accompanied this file.
  7. *
  8. * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  9. * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  10. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  11. */
  12.  
  13. #include "BzfMedia.h"
  14. #include "TimeKeeper.h"
  15. #if !defined(HAVE_SDL) || defined(_WIN32)
  16. #include "wave.h"
  17. #endif
  18. #include "MediaFile.h"
  19. #include <string.h>
  20. #include <string>
  21. #include <stdio.h>
  22. #include "CacheManager.h"
  23.  
  24. BzfMedia::BzfMedia() : mediaDir(DEFAULT_MEDIA_DIR) {}
  25. BzfMedia::~BzfMedia() {}
  26.  
  27. double BzfMedia::stopwatch(bool start)
  28. {
  29. static TimeKeeper prev;
  30. if (start)
  31. {
  32. prev = TimeKeeper::getCurrent();
  33. return 0.0;
  34. }
  35. else
  36. return (double)(TimeKeeper::getCurrent() - prev);
  37. }
  38.  
  39. std::string BzfMedia::getMediaDirectory() const
  40. {
  41. return mediaDir;
  42. }
  43.  
  44. void BzfMedia::setMediaDirectory(const std::string& _dir)
  45. {
  46. mediaDir = _dir;
  47. }
  48.  
  49. unsigned char* BzfMedia::readImage(const std::string& filename,
  50. int& width, int& height, int& depth) const
  51. {
  52. // try mediaDir/filename
  53. std::string name = makePath(mediaDir, filename);
  54. unsigned char* image = doReadImage(name, width, height, depth);
  55. if (image) return image;
  56.  
  57. // try filename as is
  58. image = doReadImage(filename, width, height, depth);
  59. if (image) return image;
  60.  
  61. #if defined(INSTALL_DATA_DIR)
  62. // try standard-mediaDir/filename
  63. name = makePath(INSTALL_DATA_DIR, filename);
  64. image = doReadImage(name, width, height, depth);
  65. if (image) return image;
  66. #endif
  67.  
  68. // try mediaDir/filename with replaced extension
  69. name = replaceExtension(makePath(mediaDir, filename), getImageExtension());
  70. image = doReadImage(name, width, height, depth);
  71. if (image) return image;
  72.  
  73. // try filename with replaced extension
  74. name = replaceExtension(filename, getImageExtension());
  75. image = doReadImage(name, width, height, depth);
  76. if (image) return image;
  77.  
  78. #if defined(INSTALL_DATA_DIR)
  79. // try standard-mediaDir/filename with replaced extension
  80. name = makePath(INSTALL_DATA_DIR, filename);
  81. name = replaceExtension(name, getImageExtension());
  82. image = doReadImage(name, width, height, depth);
  83. if (image) return image;
  84. #endif
  85.  
  86. // try data/filename
  87. name = makePath(DEFAULT_MEDIA_DIR, filename);
  88. image = doReadImage(name, width, height, depth);
  89. if (image) return image;
  90.  
  91. // try data/filename with replaced extension
  92. name = replaceExtension(makePath(DEFAULT_MEDIA_DIR, filename), getImageExtension());
  93. image = doReadImage(name, width, height, depth);
  94. if (image) return image;
  95.  
  96. // try ../data/filename
  97. name = "../";
  98. name += DEFAULT_MEDIA_DIR;
  99. name = makePath(name, filename);
  100. image = doReadImage(name, width, height, depth);
  101. if (image) return image;
  102.  
  103. // try ../data/filename with replaced extension
  104. name = "../";
  105. name += DEFAULT_MEDIA_DIR;
  106. name = replaceExtension(makePath(name, filename), getImageExtension());
  107. image = doReadImage(name, width, height, depth);
  108. if (image) return image;
  109.  
  110. // try ../../data/filename
  111. name = "../../";
  112. name += DEFAULT_MEDIA_DIR;
  113. name = makePath(name, filename);
  114. image = doReadImage(name, width, height, depth);
  115. if (image) return image;
  116.  
  117. // try ../../data/filename with replaced extension
  118. name = "../../";
  119. name += DEFAULT_MEDIA_DIR;
  120. name = replaceExtension(makePath(name, filename), getImageExtension());
  121. image = doReadImage(name, width, height, depth);
  122. if (image) return image;
  123.  
  124. #ifndef DEBUG
  125. std::cout << "Unable to locate [" << filename << "] image file (media dir is set to " << mediaDir << ")" << std::endl;
  126. #endif
  127.  
  128. return NULL;
  129. }
  130. /* Get the sound file. */
  131. float* BzfMedia::readSound(const std::string& filename,
  132. int& numFrames, int& rate) const
  133. {
  134. // try mediaDir/filename IE: the data folder.
  135. std::string name = makePath(mediaDir, filename);
  136. float* sound = doReadSound(name, numFrames, rate);
  137. if (sound) return sound;
  138.  
  139. // try filename as is IE: direct path.
  140. sound = doReadSound(filename, numFrames, rate);
  141. if (sound) return sound;
  142.  
  143. #if defined(INSTALL_DATA_DIR)
  144. // try standard-mediaDir/filename
  145. name = makePath(INSTALL_DATA_DIR, filename);
  146. sound = doReadSound(name, numFrames, rate);
  147. if (sound) return sound;
  148. #endif
  149.  
  150. // try mediaDir/filename with replaced extension
  151. name = replaceExtension(makePath(mediaDir, filename), getSoundExtension());
  152. sound = doReadSound(name, numFrames, rate);
  153. if (sound) return sound;
  154.  
  155. // try filename with replaced extension
  156. name = replaceExtension(filename, getSoundExtension());
  157. sound = doReadSound(name, numFrames, rate);
  158. if (sound) return sound;
  159.  
  160. #if defined(INSTALL_DATA_DIR)
  161. // try mediaDir/filename with replaced extension
  162. name = makePath(INSTALL_DATA_DIR, filename);
  163. name = replaceExtension(name, getSoundExtension());
  164. sound = doReadSound(name, numFrames, rate);
  165. if (sound) return sound;
  166. #endif
  167.  
  168. // try mediaDir/filename
  169. name = makePath(DEFAULT_MEDIA_DIR, filename);
  170. sound = doReadSound(name, numFrames, rate);
  171. if (sound) return sound;
  172.  
  173. // try mediaDir/filename with replaced extension
  174. name = replaceExtension(makePath(DEFAULT_MEDIA_DIR, filename), getSoundExtension());
  175. sound = doReadSound(name, numFrames, rate);
  176. if (sound) return sound;
  177.  
  178. // try mediaDir/filename
  179. name = "../";
  180. name += DEFAULT_MEDIA_DIR;
  181. name = makePath(name, filename);
  182. sound = doReadSound(name, numFrames, rate);
  183. if (sound) return sound;
  184.  
  185. // try mediaDir/filename with replaced extension
  186. name = "../";
  187. name += DEFAULT_MEDIA_DIR;
  188. name = replaceExtension(makePath(name, filename), getSoundExtension());
  189. sound = doReadSound(name, numFrames, rate);
  190. if (sound) return sound;
  191.  
  192. // try mediaDir/filename
  193. name = "../../";
  194. name += DEFAULT_MEDIA_DIR;
  195. name = makePath(name, filename);
  196. sound = doReadSound(name, numFrames, rate);
  197. if (sound) return sound;
  198.  
  199. // try mediaDir/filename with replaced extension
  200. name = "../../";
  201. name += DEFAULT_MEDIA_DIR;
  202. name = replaceExtension(makePath(name, filename), getSoundExtension());
  203. sound = doReadSound(name, numFrames, rate);
  204. if (sound) return sound;
  205.  
  206. // try the cache...
  207. name = makePath(name, CACHEMGR.getLocalName(filename));
  208. sound = doReadSound(name, numFrames, rate);
  209. if (sound) return sound;
  210.  
  211.  
  212. #ifndef DEBUG
  213. std::cout << "Unable to locate [" << filename << "] audio file (media dir is set to " << mediaDir << ")" << std::endl;
  214. #endif
  215.  
  216. return NULL;
  217. }
  218.  
  219. std::string BzfMedia::makePath(const std::string& dir,
  220. const std::string& filename) const
  221. {
  222. if ((dir.length() == 0) || filename[0] == '/') return filename;
  223. std::string path = dir;
  224. path += "/";
  225. path += filename;
  226. return path;
  227. }
  228.  
  229. std::string BzfMedia::replaceExtension(
  230. const std::string& pathname,
  231. const std::string& extension) const
  232. {
  233. std::string newName;
  234.  
  235. const int extPosition = findExtension(pathname);
  236. if (extPosition == 0)
  237. newName = pathname;
  238. else
  239. newName = pathname.substr(0, extPosition);
  240.  
  241. newName += ".";
  242. newName += extension;
  243. return newName;
  244. }
  245.  
  246. int BzfMedia::findExtension(const std::string& pathname) const
  247. {
  248. int dot = pathname.rfind(".");
  249. int slash = pathname.rfind("/");
  250. return ((slash > dot) ? 0 : dot);
  251. }
  252.  
  253. std::string BzfMedia::getImageExtension() const
  254. {
  255. return std::string("png");
  256. }
  257.  
  258. std::string BzfMedia::getSoundExtension() const
  259. {
  260. return std::string("wav");
  261. }
  262.  
  263. unsigned char* BzfMedia::doReadImage(const std::string& filename,
  264. int& dx, int& dy, int&) const
  265. {
  266. return MediaFile::readImage( filename, &dx, &dy );
  267. }
  268.  
  269. int16_t BzfMedia::getShort(const void* ptr)
  270. {
  271. const unsigned char* data = (const unsigned char*)ptr;
  272. return ((int16_t)data[0] << 8) + (int16_t)data[1];
  273. }
  274.  
  275. uint16_t BzfMedia::getUShort(const void* ptr)
  276. {
  277. const unsigned char* data = (const unsigned char*)ptr;
  278. return ((uint16_t)data[0] << 8) + (uint16_t)data[1];
  279. }
  280.  
  281. int32_t BzfMedia::getLong(const void* ptr)
  282. {
  283. const unsigned char* data = (const unsigned char*)ptr;
  284. return ((int32_t)data[0] << 24) + ((int32_t)data[1] << 16) +
  285. ((int32_t)data[2] << 8) + (int32_t)data[3];
  286. }
  287.  
  288. bool BzfMedia::doReadVerbatim(FILE* file,
  289. int dx, int dy, int dz,
  290. unsigned char* image)
  291. {
  292. // zero image data
  293. memset(image, 0, 4 * dx * dy);
  294.  
  295. // how many channels to read?
  296. if (dz > 4)
  297. dz = 4;
  298.  
  299. // read each channel one after the other
  300. unsigned char row[4096];
  301. for (int k = 0; k < dz; ++k)
  302. {
  303. unsigned char* dst = image + k;
  304. for (int j = 0; j < dy; ++j)
  305. {
  306. // read raw data
  307. if (fread(row, dx, 1, file) != 1)
  308. return false;
  309.  
  310. // reformat
  311. for (int i = 0; i < dx; ++i)
  312. {
  313. *dst = row[i];
  314. dst += 4;
  315. }
  316. }
  317. }
  318. return true;
  319. }
  320.  
  321. bool BzfMedia::doReadRLE(FILE* file,
  322. int dx, int dy, int dz,
  323. unsigned char* image)
  324. {
  325. // zero image data
  326. memset(image, 0, 4 * dx * dy);
  327.  
  328. // how many channels to read?
  329. if (dz > 4)
  330. dz = 4;
  331.  
  332. // read offset tables
  333. const int tableSize = dy * dz;
  334. int32_t* startTable = new int32_t[tableSize];
  335. if (fread(startTable, 4 * tableSize, 1, file) != 1)
  336. {
  337. delete[] startTable;
  338. return false;
  339. }
  340. int32_t* lengthTable = new int32_t[tableSize];
  341. if (fread(lengthTable, 4 * tableSize, 1, file) != 1)
  342. {
  343. delete[] startTable;
  344. delete[] lengthTable;
  345. return false;
  346. }
  347.  
  348. // convert offset tables to proper endianness
  349. for (int n = 0; n < tableSize; ++n)
  350. {
  351. startTable[n] = getLong(startTable + n);
  352. lengthTable[n] = getLong(lengthTable + n);
  353. }
  354.  
  355. // read each channel one after the other
  356. unsigned char row[4096];
  357. for (int k = 0; k < dz; ++k)
  358. {
  359. unsigned char* dst = image + k;
  360. for (int j = 0; j < dy; ++j)
  361. {
  362. // read raw data
  363. const int32_t length = lengthTable[j + k * dy];
  364. if (fseek(file, startTable[j + k * dy], SEEK_SET) < 0 ||
  365. fread(row, length, 1, file) != 1)
  366. {
  367. delete[] startTable;
  368. delete[] lengthTable;
  369. return false;
  370. }
  371.  
  372. // decode
  373. unsigned char* src = row;
  374. while (1)
  375. {
  376. // check for error in image
  377. if (src - row >= length)
  378. {
  379. delete[] startTable;
  380. delete[] lengthTable;
  381. return false;
  382. }
  383.  
  384. // get next code
  385. const unsigned char type = *src++;
  386. int count = (int)(type & 0x7f);
  387.  
  388. // zero code means end of row
  389. if (count == 0)
  390. break;
  391.  
  392. if (type & 0x80)
  393. {
  394. // copy count pixels
  395. while (count--)
  396. {
  397. *dst = *src++;
  398. dst += 4;
  399. }
  400. }
  401. else
  402. {
  403. // repeat pixel count times
  404. const unsigned char pixel = *src++;
  405. while (count--)
  406. {
  407. *dst = pixel;
  408. dst += 4;
  409. }
  410. }
  411. }
  412. }
  413. }
  414.  
  415. delete[] startTable;
  416. delete[] lengthTable;
  417. return true;
  418. }
  419.  
  420. #if defined(HAVE_SDL) && !defined(_WIN32)
  421. float* BzfMedia::doReadSound(const std::string&, int&, int&) const
  422. {
  423. return NULL;
  424. }
  425. #else
  426. float* BzfMedia::doReadSound(const std::string& filename,
  427. int& numFrames, int& rate) const
  428. {
  429. short format, channels, width;
  430. long speed;
  431. FILE* file;
  432. char *rawdata, *rawpos;
  433. int i;
  434. float *data;
  435.  
  436. file = openWavFile(filename.c_str(), &format, &speed, &numFrames, &channels, &width);
  437. if (!file) return 0;
  438. rate=speed;
  439. rawdata=new char[numFrames*width*channels];
  440. if (readWavData(file, rawdata, numFrames*channels, width))
  441. {
  442. fprintf(stderr, "Failed to read the wav data\n");
  443. delete [] rawdata;
  444. closeWavFile(file);
  445. return 0;
  446. }
  447. closeWavFile(file);
  448.  
  449. #ifdef HALF_RATE_AUDIO
  450. numFrames/=2;
  451. rate/=2;
  452. #endif
  453. data = new float[2*numFrames];
  454. rawpos=rawdata;
  455. for (i=0; i<numFrames; i++)
  456. {
  457. if (channels==1)
  458. {
  459. if (width==1)
  460. {
  461. data[i*2]=data[i*2+1] = (*(signed char*)rawpos)*256.0f;
  462. rawpos++;
  463. #ifdef HALF_RATE_AUDIO
  464. rawpos++;
  465. #endif
  466. }
  467. else
  468. {
  469. data[i*2]=data[i*2+1] = *(short*)rawpos;
  470. rawpos+=2;
  471. #ifdef HALF_RATE_AUDIO
  472. rawpos+=2;
  473. #endif
  474. }
  475. }
  476. else
  477. {
  478. if (width==1)
  479. {
  480. data[i*2] = (*(signed char*)rawpos)*256.0f;
  481. rawpos++;
  482. data[i*2+1] = (*(signed char*)rawpos)*256.0f;
  483. rawpos++;
  484. #ifdef HALF_RATE_AUDIO
  485. rawpos+=2;
  486. #endif
  487. }
  488. else
  489. {
  490. data[i*2] = *(short*)rawpos;
  491. rawpos+=2;
  492. data[i*2+1] = *(short*)rawpos;
  493. rawpos+=2;
  494. #ifdef HALF_RATE_AUDIO
  495. rawpos+=4;
  496. #endif
  497.  
  498. }
  499. }
  500. }
  501. delete [] rawdata;
  502. return data;
  503. }
  504. #endif
  505.  
  506. // Setting Audio Driver
  507. void BzfMedia::setDriver(std::string)
  508. {
  509. }
  510.  
  511. // Setting Audio Device
  512. void BzfMedia::setDevice(std::string)
  513. {
  514. }
  515.  
  516. void BzfMedia::audioDriver(std::string& driverName)
  517. {
  518. driverName = "";
  519. }
  520.  
  521. // Local Variables: ***
  522. // mode: C++ ***
  523. // tab-width: 4 ***
  524. // c-basic-offset: 4 ***
  525. // indent-tabs-mode: nil ***
  526. // End: ***
  527. // ex: shiftwidth=4 tabstop=4
  528.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement