AudioSourceManager.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AudioSourceManager.h>
  9. #include <AudioInput/AudioInputFile.h>
  10. #include <AudioInput/AudioInputMicrophone.h>
  11. #include <AudioInput/AudioInputStream.h>
  12. #include <AzCore/std/parallel/lock.h>
  13. #include <AK/AkWwiseSDKVersion.h>
  14. #include <AK/Plugin/AkAudioInputPlugin.h>
  15. namespace Audio
  16. {
  17. ///////////////////////////////////////////////////////////////////////////////////////////////
  18. // Audio Input Source
  19. ///////////////////////////////////////////////////////////////////////////////////////////////
  20. ///////////////////////////////////////////////////////////////////////////////////////////////
  21. bool AudioInputSource::IsFormatValid() const
  22. {
  23. // Audio Input Source has restrictions on the formats that are supported:
  24. // 16-bit Integer samples, interleaved samples
  25. // 32-bit Float samples, non-interleaved samples
  26. // The Parser doesn't care about such restrictions and is only responsible for
  27. // reading the header information and validating it.
  28. bool valid = true;
  29. if (m_config.m_sampleType == AudioInputSampleType::Int && m_config.m_bitsPerSample != 16)
  30. {
  31. valid = false;
  32. }
  33. if (m_config.m_sampleType == AudioInputSampleType::Float && m_config.m_bitsPerSample != 32)
  34. {
  35. valid = false;
  36. }
  37. if (m_config.m_sampleType == AudioInputSampleType::Unsupported)
  38. {
  39. valid = false;
  40. }
  41. if (!valid)
  42. {
  43. AZ_TracePrintf("AudioInputFile", "The file format is NOT supported! Only 16-bit integer or 32-bit float sample types are allowed!\n"
  44. "Current Format: (%s / %d)\n", m_config.m_sampleType == AudioInputSampleType::Int ? "Int"
  45. : (m_config.m_sampleType == AudioInputSampleType::Float ? "Float" : "Unknown"),
  46. m_config.m_bitsPerSample);
  47. }
  48. return valid;
  49. }
  50. ///////////////////////////////////////////////////////////////////////////////////////////////
  51. void AudioInputSource::SetFormat(AkAudioFormat& format)
  52. {
  53. AkUInt32 speakerConfig = 0;
  54. switch (m_config.m_numChannels)
  55. {
  56. case 1:
  57. {
  58. speakerConfig = AK_SPEAKER_SETUP_MONO;
  59. break;
  60. }
  61. case 2:
  62. {
  63. speakerConfig = AK_SPEAKER_SETUP_STEREO;
  64. break;
  65. }
  66. case 6:
  67. {
  68. speakerConfig = AK_SPEAKER_SETUP_5POINT1;
  69. break;
  70. }
  71. default:
  72. {
  73. // TODO: Test more channels
  74. return;
  75. }
  76. }
  77. AkUInt32 sampleType = 0;
  78. AkUInt32 sampleInterleaveType = 0;
  79. switch (m_config.m_bitsPerSample)
  80. {
  81. case 16:
  82. {
  83. sampleType = AK_INT;
  84. sampleInterleaveType = AK_INTERLEAVED;
  85. break;
  86. }
  87. case 32:
  88. {
  89. sampleType = AK_FLOAT;
  90. sampleInterleaveType = AK_NONINTERLEAVED;
  91. break;
  92. }
  93. default:
  94. {
  95. // Anything else and Audio Input Source doesn't support it.
  96. // But we've already checked the format when parsing the header, so we shouldn't get here.
  97. break;
  98. }
  99. }
  100. AkChannelConfig akChannelConfig(m_config.m_numChannels, speakerConfig);
  101. format.SetAll(
  102. m_config.m_sampleRate,
  103. akChannelConfig,
  104. m_config.m_bitsPerSample,
  105. m_config.m_numChannels * m_config.m_bitsPerSample >> 3, // shift converts bits->bytes, this is the frame size
  106. sampleType,
  107. sampleInterleaveType
  108. );
  109. }
  110. ///////////////////////////////////////////////////////////////////////////////////////////////
  111. void AudioInputSource::SetSourceId(TAudioSourceId sourceId)
  112. {
  113. m_config.m_sourceId = sourceId;
  114. }
  115. ///////////////////////////////////////////////////////////////////////////////////////////////
  116. TAudioSourceId AudioInputSource::GetSourceId() const
  117. {
  118. return m_config.m_sourceId;
  119. }
  120. ///////////////////////////////////////////////////////////////////////////////////////////////
  121. // Audio Input Source Manager
  122. ///////////////////////////////////////////////////////////////////////////////////////////////
  123. ///////////////////////////////////////////////////////////////////////////////////////////////
  124. AudioSourceManager::AudioSourceManager()
  125. {
  126. }
  127. ///////////////////////////////////////////////////////////////////////////////////////////////
  128. AudioSourceManager::~AudioSourceManager()
  129. {
  130. Shutdown();
  131. }
  132. ///////////////////////////////////////////////////////////////////////////////////////////////
  133. // static
  134. AudioSourceManager& AudioSourceManager::Get()
  135. {
  136. static AudioSourceManager s_manager;
  137. return s_manager;
  138. }
  139. ///////////////////////////////////////////////////////////////////////////////////////////////
  140. // static
  141. void AudioSourceManager::Initialize()
  142. {
  143. // Wwise Api call to setup the callbacks used by Audio Input Sources.
  144. SetAudioInputCallbacks(AudioSourceManager::ExecuteCallback, AudioSourceManager::GetFormatCallback);
  145. }
  146. ///////////////////////////////////////////////////////////////////////////////////////////////
  147. void AudioSourceManager::Shutdown()
  148. {
  149. AZStd::lock_guard<AZStd::mutex> lock(m_inputMutex);
  150. m_activeAudioInputs.clear();
  151. m_inactiveAudioInputs.clear();
  152. }
  153. ///////////////////////////////////////////////////////////////////////////////////////////////
  154. bool AudioSourceManager::CreateSource(const SAudioInputConfig& sourceConfig)
  155. {
  156. AZStd::unique_ptr<AudioInputSource> ptr = nullptr;
  157. switch (sourceConfig.m_sourceType)
  158. {
  159. case AudioInputSourceType::PcmFile:
  160. case AudioInputSourceType::WavFile:
  161. //case AudioInputSourceType::OggFile:
  162. //case AudioInputSourceType::OpusFile:
  163. {
  164. if (!sourceConfig.m_sourceFilename.empty())
  165. {
  166. ptr.reset(aznew AudioInputFile(sourceConfig));
  167. }
  168. break;
  169. }
  170. case AudioInputSourceType::Microphone:
  171. {
  172. ptr.reset(aznew AudioInputMicrophone(sourceConfig));
  173. break;
  174. }
  175. case AudioInputSourceType::ExternalStream:
  176. {
  177. ptr.reset(aznew AudioInputStreaming(sourceConfig));
  178. break;
  179. }
  180. case AudioInputSourceType::Synthesis: // Will need to allow setting a user-defined Generate callback.
  181. default:
  182. {
  183. AZ_TracePrintf("AudioSourceManager", "AudioSourceManager::CreateSource - The type of AudioInputSource requested is not supported yet!\n");
  184. return INVALID_AUDIO_SOURCE_ID;
  185. }
  186. }
  187. if (!ptr || !ptr->IsOk())
  188. { // this check could change in the future as we add asynch loading.
  189. return false;
  190. }
  191. AZStd::lock_guard<AZStd::mutex> lock(m_inputMutex);
  192. ptr->SetSourceId(sourceConfig.m_sourceId);
  193. m_inactiveAudioInputs.emplace(sourceConfig.m_sourceId, AZStd::move(ptr));
  194. return true;
  195. }
  196. ///////////////////////////////////////////////////////////////////////////////////////////////
  197. void AudioSourceManager::ActivateSource(TAudioSourceId sourceId, AkPlayingID playingId)
  198. {
  199. AZStd::lock_guard<AZStd::mutex> lock(m_inputMutex);
  200. if (m_inactiveAudioInputs.find(sourceId) != m_inactiveAudioInputs.end())
  201. {
  202. if (m_activeAudioInputs.find(playingId) == m_activeAudioInputs.end())
  203. {
  204. m_inactiveAudioInputs[sourceId]->SetSourceId(sourceId);
  205. m_activeAudioInputs[playingId] = AZStd::move(m_inactiveAudioInputs[sourceId]);
  206. m_inactiveAudioInputs.erase(sourceId);
  207. m_activeAudioInputs[playingId]->OnActivated();
  208. }
  209. else
  210. {
  211. AZ_TracePrintf("AudioSourceManager", "AudioSourceManager::ActivateSource - Active source with playing Id %u already exists!\n", playingId);
  212. }
  213. }
  214. else
  215. {
  216. AZ_TracePrintf("AudioSourceManager", "AudioSourceManager::ActivateSource - Source with Id %u not found!\n", sourceId);
  217. }
  218. }
  219. ///////////////////////////////////////////////////////////////////////////////////////////////
  220. void AudioSourceManager::DeactivateSource(AkPlayingID playingId)
  221. {
  222. AZStd::lock_guard<AZStd::mutex> lock(m_inputMutex);
  223. if (m_activeAudioInputs.find(playingId) != m_activeAudioInputs.end())
  224. {
  225. TAudioSourceId sourceId = m_activeAudioInputs[playingId]->GetSourceId();
  226. if (m_inactiveAudioInputs.find(sourceId) == m_inactiveAudioInputs.end())
  227. {
  228. m_inactiveAudioInputs[sourceId] = AZStd::move(m_activeAudioInputs[playingId]);
  229. m_activeAudioInputs.erase(playingId);
  230. // Signal to the audio input source that it was deactivated! It might unload it's resources.
  231. m_inactiveAudioInputs[sourceId]->OnDeactivated();
  232. if (!m_inactiveAudioInputs[sourceId]->IsOk())
  233. {
  234. m_inactiveAudioInputs.erase(sourceId);
  235. }
  236. }
  237. else
  238. {
  239. AZ_TracePrintf("AudioSourceManager", "AudioSourceManager::DeactivateSource - Source with Id %u was already inactive!\n", sourceId);
  240. }
  241. }
  242. else
  243. {
  244. AZ_TracePrintf("AudioSourceManager", "AudioSourceManager::DeactivateSource - Active source with playing Id %u not found!\n", playingId);
  245. }
  246. }
  247. ///////////////////////////////////////////////////////////////////////////////////////////////
  248. void AudioSourceManager::DestroySource(TAudioSourceId sourceId)
  249. {
  250. AZStd::lock_guard<AZStd::mutex> lock(m_inputMutex);
  251. if (m_inactiveAudioInputs.find(sourceId) != m_inactiveAudioInputs.end())
  252. {
  253. m_inactiveAudioInputs.erase(sourceId);
  254. }
  255. else
  256. {
  257. AZ_TracePrintf("AudioSourceManager", "AudioSourceManager::DestroySource - No source with Id %u was found!\nDid you call DeactivateSource first on the playingId??\n", sourceId);
  258. }
  259. }
  260. ///////////////////////////////////////////////////////////////////////////////////////////////
  261. AkPlayingID AudioSourceManager::FindPlayingSource(TAudioSourceId sourceId)
  262. {
  263. AZStd::lock_guard<AZStd::mutex> lock(m_inputMutex);
  264. for (auto& inputPair : m_activeAudioInputs)
  265. {
  266. if (inputPair.second->GetSourceId() == sourceId)
  267. {
  268. return inputPair.first;
  269. }
  270. }
  271. return AK_INVALID_PLAYING_ID;
  272. }
  273. ///////////////////////////////////////////////////////////////////////////////////////////////
  274. // static
  275. void AudioSourceManager::ExecuteCallback(AkPlayingID playingId, AkAudioBuffer* akBuffer)
  276. {
  277. if (!akBuffer->HasData())
  278. {
  279. akBuffer->eState = AK_Fail;
  280. akBuffer->uValidFrames = 0;
  281. return;
  282. }
  283. if (akBuffer->eState == AK_NoDataNeeded)
  284. {
  285. akBuffer->eState = AK_NoDataReady;
  286. akBuffer->uValidFrames = 0;
  287. return;
  288. }
  289. AZStd::lock_guard<AZStd::mutex> lock(Get().m_inputMutex);
  290. auto inputIter = Get().m_activeAudioInputs.find(playingId);
  291. if (inputIter != Get().m_activeAudioInputs.end())
  292. {
  293. auto& audioInput = inputIter->second;
  294. if (audioInput)
  295. {
  296. // this will set the uValidFrames and eState for us.
  297. audioInput->WriteOutput(akBuffer);
  298. }
  299. }
  300. else
  301. {
  302. // signal that the audio input playback should end.
  303. akBuffer->eState = AK_NoMoreData;
  304. akBuffer->uValidFrames = 0;
  305. }
  306. }
  307. ///////////////////////////////////////////////////////////////////////////////////////////////
  308. // static
  309. void AudioSourceManager::GetFormatCallback(AkPlayingID playingId, AkAudioFormat& audioFormat)
  310. {
  311. AZStd::lock_guard<AZStd::mutex> lock(Get().m_inputMutex);
  312. auto inputIter = Get().m_activeAudioInputs.find(playingId);
  313. if (inputIter != Get().m_activeAudioInputs.end())
  314. {
  315. // Set the AkAudioFormat from the AudioInputSource's SAudioInputConfig
  316. auto& audioInput = inputIter->second;
  317. if (audioInput)
  318. {
  319. audioInput->SetFormat(audioFormat);
  320. }
  321. }
  322. }
  323. } // namespace Audio