Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SoundManager.cpp 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*!
  2. * \file src/SoundManager.cpp
  3. * \brief Sound Source Manager
  4. *
  5. * \author xythobuz
  6. */
  7. #include "imgui/imgui.h"
  8. #include "global.h"
  9. #include "Camera.h"
  10. #include "Log.h"
  11. #include "system/Sound.h"
  12. #include "SoundManager.h"
  13. void SoundSource::prepare() {
  14. if (source != -1)
  15. return;
  16. float vol;
  17. int index = SoundManager::getIndex(id, &vol);
  18. if ((index < 0) || (index > Sound::numBuffers())) {
  19. Log::get(LOG_ERROR) << "Invalid SoundSource ID (" << index << ", "
  20. << Sound::numBuffers() << ")!" << Log::endl;
  21. source = -2;
  22. } else {
  23. source = Sound::addSource(index, vol, false, true);
  24. if (source < 0) {
  25. source = -2;
  26. } else {
  27. int ret = Sound::sourceAt(source, pos);
  28. if (ret < 0) {
  29. Log::get(LOG_ERROR) << "Error positioning SoundSource " << id << Log::endl;
  30. }
  31. }
  32. }
  33. }
  34. void SoundSource::play() {
  35. playing = true;
  36. if (source >= 0)
  37. Sound::play(source, false);
  38. }
  39. void SoundSource::stop() {
  40. playing = false;
  41. if (source >= 0)
  42. Sound::stop(source);
  43. }
  44. // ----------------------------------------------------------------------------
  45. std::vector<SoundSource> SoundManager::soundSources;
  46. std::vector<int> SoundManager::soundMap;
  47. std::vector<SoundDetail> SoundManager::soundDetails;
  48. std::vector<int> SoundManager::sampleIndices;
  49. void SoundManager::clear() {
  50. soundSources.clear();
  51. soundMap.clear();
  52. soundDetails.clear();
  53. sampleIndices.clear();
  54. Sound::clear();
  55. }
  56. int SoundManager::prepareSources() {
  57. for (int i = 0; i < soundMap.size(); i++) {
  58. float vol;
  59. SoundDetail* sd;
  60. int index = getIndex(i, &vol, &sd);
  61. if ((index >= 0) && (index < Sound::numBuffers())) {
  62. int ret = Sound::addSource(index, vol, true, false);
  63. if (ret < 0) {
  64. Log::get(LOG_ERROR) << "Error adding SoundSource " << index << Log::endl;
  65. }
  66. sd->setSource(ret);
  67. }
  68. }
  69. for (int i = 0; i < soundSources.size(); i++) {
  70. soundSources.at(i).prepare();
  71. soundSources.at(i).play();
  72. }
  73. return 0;
  74. }
  75. void SoundManager::addSoundSource(glm::vec3 p, int id, int flags) {
  76. soundSources.emplace_back(p, id, flags);
  77. }
  78. void SoundManager::addSoundMapEntry(int id) {
  79. soundMap.push_back(id);
  80. }
  81. void SoundManager::addSoundDetail(int sample, float volume) {
  82. soundDetails.emplace_back(sample, volume);
  83. }
  84. void SoundManager::addSampleIndex(int index) {
  85. sampleIndices.push_back(index);
  86. }
  87. int SoundManager::getIndex(int index, float* volume, SoundDetail** sd) {
  88. if (index <= -1)
  89. return -1;
  90. if (index >= soundMap.size())
  91. return -2; // SoundMap not big enough
  92. index = soundMap.at(index);
  93. if (index <= -1)
  94. return -3; // SoundMap has no entry here (-1)
  95. if (index >= soundDetails.size())
  96. return -4; // SoundMap entry is bigger than SoundDetails
  97. SoundDetail s = soundDetails.at(index);
  98. if (sd != nullptr)
  99. *sd = &soundDetails.at(index);
  100. if (volume != nullptr)
  101. *volume = s.getVolume();
  102. if (s.getSample() <= -1)
  103. return -5; // SoundDetail has no entry here (-1)
  104. if (s.getSample() >= sampleIndices.size())
  105. return -6; // SoundDetail entry is bigger than SampleIndices
  106. index = sampleIndices.at(s.getSample());
  107. if (index <= -1)
  108. return -7; // SampleIndices has no entry here (-1)
  109. return index;
  110. }
  111. int SoundManager::playSound(int index) {
  112. if ((index >= 0) && (index < soundMap.size())) {
  113. SoundDetail* sd;
  114. int i = getIndex(index, nullptr, &sd);
  115. if ((i < 0) || (i >= Sound::numBuffers()))
  116. return -2;
  117. Sound::play(sd->getSource(), true);
  118. return 0;
  119. } else {
  120. return -1;
  121. }
  122. }
  123. void SoundManager::display() {
  124. if (ImGui::CollapsingHeader("Sound Sources")) {
  125. ImGui::Columns(5, "soundsources");
  126. ImGui::Text("No");
  127. ImGui::NextColumn();
  128. ImGui::Text("ID");
  129. ImGui::NextColumn();
  130. ImGui::Text("Flags");
  131. ImGui::NextColumn();
  132. ImGui::Text("Pos");
  133. ImGui::NextColumn();
  134. ImGui::Text("Tools");
  135. ImGui::NextColumn();
  136. ImGui::Separator();
  137. static bool offsets = false;
  138. if (!offsets) {
  139. ImGui::SetColumnOffset(1, 40.0f);
  140. ImGui::SetColumnOffset(2, 80.0f);
  141. ImGui::SetColumnOffset(3, 130.0f);
  142. ImGui::SetColumnOffset(4, 350.0f);
  143. offsets = true;
  144. }
  145. for (int i = 0; i < soundSources.size(); i++) {
  146. auto& ss = soundSources.at(i);
  147. ImGui::Text("%03d", i);
  148. ImGui::NextColumn();
  149. ImGui::Text("%d", ss.getID());
  150. ImGui::NextColumn();
  151. ImGui::Text("0x%X", ss.getFlags());
  152. ImGui::NextColumn();
  153. ImGui::Text("%.1f %.1f %.1f", ss.getPos().x, ss.getPos().y, ss.getPos().z);
  154. ImGui::NextColumn();
  155. ImGui::PushID(i);
  156. if (ImGui::Button("Warp")) {
  157. Camera::setPosition(ss.getPos());
  158. }
  159. ImGui::SameLine();
  160. if (ImGui::Button("Play")) {
  161. playSound(soundSources.at(i).getID());
  162. }
  163. ImGui::SameLine();
  164. if (ss.isPlaying()) {
  165. if (ImGui::Button("Stop")) {
  166. ss.stop();
  167. }
  168. } else {
  169. if (ImGui::Button("Start")) {
  170. ss.play();
  171. }
  172. }
  173. ImGui::PopID();
  174. ImGui::NextColumn();
  175. }
  176. ImGui::Columns(1);
  177. }
  178. if (ImGui::CollapsingHeader("Sound Details")) {
  179. ImGui::Columns(4, "sounddetails");
  180. ImGui::Text("No");
  181. ImGui::NextColumn();
  182. ImGui::Text("Vol");
  183. ImGui::NextColumn();
  184. ImGui::Text("Sample");
  185. ImGui::NextColumn();
  186. ImGui::Text("Tools");
  187. ImGui::NextColumn();
  188. ImGui::Separator();
  189. static bool offsets2 = false;
  190. if (!offsets2) {
  191. ImGui::SetColumnOffset(1, 40.0f);
  192. ImGui::SetColumnOffset(2, 80.0f);
  193. ImGui::SetColumnOffset(3, 180.0f);
  194. offsets2 = true;
  195. }
  196. for (int i = 0; i < soundDetails.size(); i++) {
  197. auto& sd = soundDetails.at(i);
  198. ImGui::Text("%03d", i);
  199. ImGui::NextColumn();
  200. ImGui::Text("%.2f", sd.getVolume());
  201. ImGui::NextColumn();
  202. if ((sd.getSample() < 0) || (sd.getSample() >= sampleIndices.size())) {
  203. ImGui::Text("%03d --> ???", sd.getSample());
  204. } else {
  205. ImGui::Text("%03d --> %03d", sd.getSample(), sampleIndices.at(sd.getSample()));
  206. }
  207. ImGui::NextColumn();
  208. ImGui::PushID(i);
  209. if (sd.getSource() >= 0) {
  210. if (ImGui::Button("Play")) {
  211. Sound::play(sd.getSource(), true);
  212. }
  213. }
  214. ImGui::PopID();
  215. ImGui::NextColumn();
  216. }
  217. ImGui::Columns(1);
  218. }
  219. if (ImGui::CollapsingHeader("Sound Map Player")) {
  220. if (!Sound::getEnabled()) {
  221. ImGui::Text("Please enable Sound first!");
  222. if (ImGui::Button("Enable Sound!")) {
  223. Sound::setEnabled(true);
  224. }
  225. return;
  226. } else if (Sound::numBuffers() == 0) {
  227. ImGui::Text("No Sounds currently loaded!");
  228. return;
  229. }
  230. static int index = 0;
  231. ImGui::Text("Map");
  232. ImGui::SameLine();
  233. ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f);
  234. ImGui::SliderInt("##soundslide", &index, 0, soundMap.size() - 1);
  235. ImGui::PopItemWidth();
  236. ImGui::SameLine();
  237. if (ImGui::Button("+##soundplus", ImVec2(0, 0))) {
  238. if (index < (soundMap.size() - 1))
  239. index++;
  240. else
  241. index = 0;
  242. }
  243. ImGui::SameLine();
  244. if (ImGui::Button("-##soundminus", ImVec2(0, 0))) {
  245. if (index > 0)
  246. index--;
  247. else
  248. index = soundMap.size() - 1;
  249. }
  250. ImGui::SameLine();
  251. if (ImGui::Button("Play##soundplay")) {
  252. playSound(index);
  253. }
  254. ImGui::SameLine();
  255. ImGui::Text("%d", getIndex(index));
  256. }
  257. }