audioFunctions.cc 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _ASSET_MANAGER_H_
  23. #include "assets/assetManager.h"
  24. #endif
  25. #include "platform/platform.h"
  26. #ifndef _PLATFORMAUDIO_H_
  27. #include "platform/platformAudio.h"
  28. #endif
  29. #ifndef _SIMBASE_H_
  30. #include "sim/simBase.h"
  31. #endif
  32. #ifndef _AUDIODATABLOCK_H_
  33. #include "audio/audioDataBlock.h"
  34. #endif
  35. #ifndef _AUDIO_ASSET_H_
  36. #include "audio/audioAsset.h"
  37. #endif
  38. #ifdef TORQUE_OS_IOS
  39. #include "platformiOS/iOSStreamSource.h"
  40. #endif
  41. extern ALuint alxGetWaveLen(ALuint buffer);
  42. extern F32 mAudioChannelVolumes[Audio::AudioVolumeChannels];
  43. //--------------------------------------------------------------------------
  44. // Expose all al get/set methods...
  45. //--------------------------------------------------------------------------
  46. enum AL_GetSetBits{
  47. Source = BIT(0),
  48. Listener = BIT(1),
  49. Context = BIT(2),
  50. Environment = BIT(3),
  51. Get = BIT(4),
  52. Set = BIT(5),
  53. Int = BIT(6),
  54. Float = BIT(7),
  55. Float3 = BIT(8),
  56. Float6 = BIT(9)
  57. };
  58. static ALenum getEnum(const char * name, U32 flags)
  59. {
  60. AssertFatal(name, "Audio getEnum: bad param");
  61. static struct {
  62. const char * mName;
  63. ALenum mAlenum;
  64. U32 mFlags;
  65. } table[] = {
  66. //-----------------------------------------------------------------------------------------------------------------
  67. // "name" ENUM Flags
  68. //-----------------------------------------------------------------------------------------------------------------
  69. { "AL_GAIN", AL_GAIN, (Source|Listener|Get|Set|Float) },
  70. { "AL_GAIN_LINEAR", AL_GAIN_LINEAR, (Source|Listener|Get|Set|Float) },
  71. { "AL_PITCH", AL_PITCH, (Source|Get|Set|Float) },
  72. { "AL_REFERENCE_DISTANCE", AL_REFERENCE_DISTANCE, (Source|Get|Set|Float) },
  73. { "AL_MAX_DISTANCE", AL_MAX_DISTANCE, (Source|Get|Set|Float) },
  74. { "AL_CONE_OUTER_GAIN", AL_CONE_OUTER_GAIN, (Source|Get|Set|Float) },
  75. { "AL_POSITION", AL_POSITION, (Source|Listener|Get|Set|Float3) },
  76. { "AL_DIRECTION", AL_DIRECTION, (Source|Get|Set|Float3) },
  77. { "AL_VELOCITY", AL_VELOCITY, (Source|Listener|Get|Set|Float3) },
  78. { "AL_ORIENTATION", AL_ORIENTATION, (Listener|Set|Float6) },
  79. { "AL_CONE_INNER_ANGLE", AL_CONE_INNER_ANGLE, (Source|Get|Set|Int) },
  80. { "AL_CONE_OUTER_ANGLE", AL_CONE_OUTER_ANGLE, (Source|Get|Set|Int) },
  81. { "AL_LOOPING", AL_LOOPING, (Source|Get|Set|Int) },
  82. //{ "AL_STREAMING", AL_STREAMING, (Source|Get|Set|Int) },
  83. //{ "AL_BUFFER", AL_BUFFER, (Source|Get|Set|Int) },
  84. { "AL_VENDOR", AL_VENDOR, (Context|Get) },
  85. { "AL_VERSION", AL_VERSION, (Context|Get) },
  86. { "AL_RENDERER", AL_RENDERER, (Context|Get) },
  87. { "AL_EXTENSIONS", AL_EXTENSIONS, (Context|Get) },
  88. /*
  89. // environment
  90. { "AL_ENV_ROOM_IASIG", AL_ENV_ROOM_IASIG, (Environment|Get|Set|Int) },
  91. { "AL_ENV_ROOM_HIGH_FREQUENCY_IASIG", AL_ENV_ROOM_HIGH_FREQUENCY_IASIG, (Environment|Get|Set|Int) },
  92. { "AL_ENV_REFLECTIONS_IASIG", AL_ENV_REFLECTIONS_IASIG, (Environment|Get|Set|Int) },
  93. { "AL_ENV_REVERB_IASIG", AL_ENV_REVERB_IASIG, (Environment|Get|Set|Int) },
  94. { "AL_ENV_ROOM_ROLLOFF_FACTOR_IASIG", AL_ENV_ROOM_ROLLOFF_FACTOR_IASIG, (Environment|Get|Set|Float) },
  95. { "AL_ENV_DECAY_TIME_IASIG", AL_ENV_DECAY_TIME_IASIG, (Environment|Get|Set|Float) },
  96. { "AL_ENV_DECAY_HIGH_FREQUENCY_RATIO_IASIG", AL_ENV_DECAY_HIGH_FREQUENCY_RATIO_IASIG, (Environment|Get|Set|Float) },
  97. { "AL_ENV_REFLECTIONS_DELAY_IASIG", AL_ENV_REFLECTIONS_DELAY_IASIG, (Environment|Get|Set|Float) },
  98. { "AL_ENV_REVERB_DELAY_IASIG", AL_ENV_REVERB_DELAY_IASIG, (Environment|Get|Set|Float) },
  99. { "AL_ENV_DIFFUSION_IASIG", AL_ENV_DIFFUSION_IASIG, (Environment|Get|Set|Float) },
  100. { "AL_ENV_DENSITY_IASIG", AL_ENV_DENSITY_IASIG, (Environment|Get|Set|Float) },
  101. { "AL_ENV_HIGH_FREQUENCY_REFERENCE_IASIG", AL_ENV_HIGH_FREQUENCY_REFERENCE_IASIG, (Environment|Get|Set|Float) },
  102. { "AL_ENV_ROOM_VOLUME_EXT", AL_ENV_ROOM_VOLUME_EXT, (Environment|Get|Set|Int) },
  103. { "AL_ENV_FLAGS_EXT", AL_ENV_FLAGS_EXT, (Environment|Get|Set|Int) },
  104. { "AL_ENV_EFFECT_VOLUME_EXT", AL_ENV_EFFECT_VOLUME_EXT, (Environment|Get|Set|Float) },
  105. { "AL_ENV_DAMPING_EXT", AL_ENV_DAMPING_EXT, (Environment|Get|Set|Float) },
  106. { "AL_ENV_ENVIRONMENT_SIZE_EXT", AL_ENV_ENVIRONMENT_SIZE_EXT, (Environment|Get|Set|Float) },
  107. // sample environment
  108. { "AL_ENV_SAMPLE_DIRECT_EXT", AL_ENV_SAMPLE_DIRECT_EXT, (Source|Get|Set|Int) },
  109. { "AL_ENV_SAMPLE_DIRECT_HF_EXT", AL_ENV_SAMPLE_DIRECT_HF_EXT, (Source|Get|Set|Int) },
  110. { "AL_ENV_SAMPLE_ROOM_EXT", AL_ENV_SAMPLE_ROOM_EXT, (Source|Get|Set|Int) },
  111. { "AL_ENV_SAMPLE_ROOM_HF_EXT", AL_ENV_SAMPLE_ROOM_HF_EXT, (Source|Get|Set|Int) },
  112. { "AL_ENV_SAMPLE_OUTSIDE_VOLUME_HF_EXT", AL_ENV_SAMPLE_OUTSIDE_VOLUME_HF_EXT, (Source|Get|Set|Int) },
  113. { "AL_ENV_SAMPLE_FLAGS_EXT", AL_ENV_SAMPLE_FLAGS_EXT, (Source|Get|Set|Int) },
  114. { "AL_ENV_SAMPLE_REVERB_MIX_EXT", AL_ENV_SAMPLE_REVERB_MIX_EXT, (Source|Get|Set|Float) },
  115. { "AL_ENV_SAMPLE_OBSTRUCTION_EXT", AL_ENV_SAMPLE_OBSTRUCTION_EXT, (Source|Get|Set|Float) },
  116. { "AL_ENV_SAMPLE_OBSTRUCTION_LF_RATIO_EXT", AL_ENV_SAMPLE_OBSTRUCTION_LF_RATIO_EXT, (Source|Get|Set|Float) },
  117. { "AL_ENV_SAMPLE_OCCLUSION_EXT", AL_ENV_SAMPLE_OCCLUSION_EXT, (Source|Get|Set|Float) },
  118. { "AL_ENV_SAMPLE_OCCLUSION_LF_RATIO_EXT", AL_ENV_SAMPLE_OCCLUSION_LF_RATIO_EXT, (Source|Get|Set|Float) },
  119. { "AL_ENV_SAMPLE_OCCLUSION_ROOM_RATIO_EXT", AL_ENV_SAMPLE_OCCLUSION_ROOM_RATIO_EXT, (Source|Get|Set|Float) },
  120. { "AL_ENV_SAMPLE_ROOM_ROLLOFF_EXT", AL_ENV_SAMPLE_ROOM_ROLLOFF_EXT, (Source|Get|Set|Float) },
  121. { "AL_ENV_SAMPLE_AIR_ABSORPTION_EXT", AL_ENV_SAMPLE_AIR_ABSORPTION_EXT, (Source|Get|Set|Float) },
  122. */
  123. };
  124. for(U32 i = 0; i < (sizeof(table) / sizeof(table[0])); i++)
  125. {
  126. if((table[i].mFlags & flags) != flags)
  127. continue;
  128. if(dStricmp(table[i].mName, name) == 0)
  129. return(table[i].mAlenum);
  130. }
  131. return(AL_INVALID);
  132. }
  133. //-----------------------------------------------
  134. ConsoleFunctionGroupBegin(Audio, "Functions dealing with the OpenAL audio layer.\n\n"
  135. "@see www.OpenAL.org for what these functions do. Variances from posted"
  136. " behaviour is described below.");
  137. ConsoleFunction(OpenALInitDriver, bool, 1, 1, "() Use the OpenALInitDriver function to initialize the OpenAL driver.\n"
  138. "This must be done before all other OpenAL operations.\n"
  139. "@return Returns true on successful initialization, false otherwise.\n"
  140. "@sa OpenALShutdownDriver")
  141. {
  142. if (Audio::OpenALInit())
  143. {
  144. static bool registered = false;
  145. if (!registered) {
  146. ResourceManager->registerExtension(".wav", AudioBuffer::construct);
  147. }
  148. registered = true;
  149. return true;
  150. }
  151. return false;
  152. }
  153. //-----------------------------------------------
  154. ConsoleFunction(OpenALShutdownDriver, void, 1, 1, "() Use the OpenALShutdownDriver function to stop/shut down the OpenAL driver.\n"
  155. "After this is called, you must restart the driver with OpenALInitDriver to execute any new sound operations.\n"
  156. "@return No return value.\n"
  157. "@sa OpenALInitDriver")
  158. {
  159. Audio::OpenALShutdown();
  160. }
  161. //-----------------------------------------------
  162. ConsoleFunction(OpenALRegisterExtensions, void, 1, 1, "OpenALRegisterExtensions()"
  163. "@note Currently does nothing (possibly deprecated)")
  164. {
  165. }
  166. //-----------------------------------------------
  167. ConsoleFunction(alGetString, const char *, 2, 2, "( ALEnum ) Use the alGetString function to get the string equivalent to the specified OpenAL enumerated value.\n"
  168. "@param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.\n"
  169. "@return Returns a string corresponding to the passed ALEnum")
  170. {
  171. ALenum e = getEnum(argv[1], (Context|Get));
  172. if(e == AL_INVALID)
  173. {
  174. Con::errorf(ConsoleLogEntry::General, "alGetString: invalid enum name '%s'", argv[1]);
  175. return "";
  176. }
  177. return (const char*)alGetString(e);
  178. }
  179. //--------------------------------------------------------------------------
  180. // Soundfile
  181. //--------------------------------------------------------------------------
  182. ConsoleFunction(alxGetAudioLength, S32, 2, 2, "( audio-assetId ) Use the alxGetAudioLength function to get the play-length of a specified resource sound file in milliseconds.\n"
  183. "@param audio-assetId The asset Id that specifies the audio file to check.\n"
  184. "@return Returns play-length of the audio file specified by audio-assetId in milliseconds.\n"
  185. "@sa alxGetStreamDuration, alxGetStreamPosition")
  186. {
  187. // Fetch asset Id.
  188. const char* pAssetId = argv[1];
  189. // Acquire audio asset.
  190. AudioAsset* pAudioAsset = AssetDatabase.acquireAsset<AudioAsset>( pAssetId );
  191. // Did we get the audio asset?
  192. if ( pAudioAsset == NULL )
  193. {
  194. // No, so warn.
  195. Con::warnf( "alxGetAudioLength() - Could not find audio asset '%s'.", pAssetId );
  196. return 0;
  197. }
  198. Resource<AudioBuffer> buffer = AudioBuffer::find( pAudioAsset->getAudioFile() );
  199. if ( !buffer.isNull() )
  200. {
  201. ALuint alBuffer = buffer->getALBuffer();
  202. return alxGetWaveLen( alBuffer );
  203. }
  204. // Warn.
  205. Con::warnf( "alxGetAudioLength() - Could not find audio file '%s' for asset '%s'.", pAudioAsset->getAudioFile(), pAssetId );
  206. return 0;
  207. }
  208. //--------------------------------------------------------------------------
  209. // Source
  210. //--------------------------------------------------------------------------
  211. ConsoleFunction(alxCreateSource, S32, 2, 2, "(audio-assetId) - Create a source from the specified asset Id.\n"
  212. "@param audio-assetId The asset Id to create the source from.\n"
  213. "@return The handle of the created source or 0 on error." )
  214. {
  215. // Fetch asset Id.
  216. const char* pAssetId = argv[1];
  217. // Acquire audio asset.
  218. AudioAsset* pAudioAsset = AssetDatabase.acquireAsset<AudioAsset>( pAssetId );
  219. // Did we get the audio asset?
  220. if ( pAudioAsset == NULL )
  221. {
  222. // No, so warn.
  223. Con::warnf( "alxCreateSource() - Could not find audio asset '%s'.", pAssetId );
  224. return NULL_AUDIOHANDLE;
  225. }
  226. // Fetch audio handle.
  227. AUDIOHANDLE handle = alxCreateSource( pAudioAsset );
  228. // Release asset.
  229. AssetDatabase.releaseAsset( pAssetId );
  230. return handle;
  231. }
  232. //-----------------------------------------------
  233. ConsoleFunction(alxSourcef, void, 4, 4, "( handle , ALEnum , value ) Use the alxSource* function to set a source parameter(s) as specified by the OpenAL enumerated type ALEnum.\n"
  234. "@param handle The ID (a non-negative integer) corresponding to a previously set up sound source.\n"
  235. "@param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.\n"
  236. "@param value An ALEnum type specific value corresponding to the new value for this enumerated parameters.\n"
  237. "@return No return value.\n"
  238. "@sa alxGetSource*, al*Listener*")
  239. {
  240. ALenum e = getEnum(argv[2], (Source|Set|Float));
  241. if(e == AL_INVALID)
  242. {
  243. Con::errorf(ConsoleLogEntry::General, "cAudio_alxSourcef: invalid enum name '%s'", argv[2]);
  244. return;
  245. }
  246. alxSourcef(dAtoi(argv[1]), e, dAtof(argv[3]));
  247. }
  248. //-----------------------------------------------
  249. ConsoleFunction(alxSource3f, void, 3, 6, "( handle , ALEnum , x , y , z ) Use the alxSource* function to set a source parameter(s) as specified by the OpenAL enumerated type ALEnum.\n"
  250. "@param handle The ID (a non-negative integer) corresponding to a previously set up sound source.\n"
  251. "@param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.\n"
  252. "@param x,y,z XYZ floating-point coordinates.\n"
  253. "@return No return value.\n"
  254. "@sa alxGetSource*, al*Listener*")
  255. {
  256. ALenum e = getEnum(argv[2], (Source|Set|Float3));
  257. if(e == AL_INVALID)
  258. {
  259. Con::errorf(ConsoleLogEntry::General, "cAudio_alxSource3f: invalid enum name '%s'", argv[2]);
  260. return;
  261. }
  262. if((argc != 4 && argc != 6))
  263. {
  264. Con::errorf(ConsoleLogEntry::General, "cAudio_alxSource3f: wrong number of args");
  265. return;
  266. }
  267. Point3F pos;
  268. if(argc == 4)
  269. dSscanf(argv[3], "%g %g %g", &pos.x, &pos.y, &pos.z);
  270. else
  271. {
  272. pos.x = dAtof(argv[3]);
  273. pos.y = dAtof(argv[4]);
  274. pos.z = dAtof(argv[5]);
  275. }
  276. alxSource3f(dAtoi(argv[1]), e, pos.x, pos.y, pos.z);
  277. }
  278. //-----------------------------------------------
  279. ConsoleFunction(alxSourcei, void, 4, 4, "( handle , ALEnum , value ) Use the alxSource* function to set a source parameter(s) as specified by the OpenAL enumerated type ALEnum.\n"
  280. "@param handle The ID (a non-negative integer) corresponding to a previously set up sound source.\n"
  281. "@param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.\n"
  282. "@param value An ALEnum type specific value corresponding to the new value for this enumerated parameters.\n"
  283. "@return No return value.\n"
  284. "@sa alxGetSource*, al*Listener*")
  285. {
  286. ALenum e = getEnum(argv[2], (Source|Set|Int));
  287. if(e == AL_INVALID)
  288. {
  289. Con::errorf(ConsoleLogEntry::General, "cAudio_alxSourcei: invalid enum name '%s'", argv[2]);
  290. return;
  291. }
  292. alxSourcei(dAtoi(argv[1]), e, dAtoi(argv[3]));
  293. }
  294. //-----------------------------------------------
  295. ConsoleFunction(alxGetSourcef, F32, 3, 3, "( handle , ALEnum ) Use the alxGetSource* function to get the current value of a source parameter, as specified by ALEnum.\n"
  296. "Depending on the ALEnum you need to acquire, be sure to use the correct version (i.e. correct return type) of alxGetSource*.\n"
  297. "@param handle The ID (a non-negative integer) corresponding to a previously set up sound source.\n"
  298. "@param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.\n"
  299. "@return Returns current value of parameter specified by ALEnum for source identified by handle.\n"
  300. "@sa alxSource*, al*GetListener*")
  301. {
  302. ALenum e = getEnum(argv[2], (Source|Get|Float));
  303. if(e == AL_INVALID)
  304. {
  305. Con::errorf(ConsoleLogEntry::General, "cAudio_alxGetSourcef: invalid enum name '%s'", argv[2]);
  306. return(0.f);
  307. }
  308. F32 value;
  309. alxGetSourcef(dAtoi(argv[1]), e, &value);
  310. return(value);
  311. }
  312. //-----------------------------------------------
  313. ConsoleFunction(alxGetSource3f, const char *, 3, 3, "( handle , ALEnum ) Use the alxGetSource* function to get the current value of a source parameter, as specified by ALEnum.\n"
  314. "Depending on the ALEnum you need to acquire, be sure to use the correct version (i.e. correct return type) of alxGetSource*.\n"
  315. "@param handle The ID (a non-negative integer) corresponding to a previously set up sound source.\n"
  316. "@param ALEnum A string containing an OpenAL enumerated type name.\n"
  317. "@return Returns current value of parameter specified by ALEnum for source identified by handle.\n"
  318. "@sa alxSource*, al*GetListener*")
  319. {
  320. ALenum e = getEnum(argv[2], (Source|Get|Float));
  321. if(e == AL_INVALID)
  322. {
  323. Con::errorf(ConsoleLogEntry::General, "cAudio_alxGetSource3f: invalid enum name '%s'", argv[2]);
  324. return("0 0 0");
  325. }
  326. F32 value1, value2, value3;
  327. alxGetSource3f(dAtoi(argv[1]), e, &value1, &value2, &value3);
  328. char * ret = Con::getReturnBuffer(64);
  329. dSprintf(ret, 64, "%7.3f %7.3 %7.3", value1, value2, value3);
  330. return(ret);
  331. }
  332. //-----------------------------------------------
  333. ConsoleFunction(alxGetSourcei, S32, 3, 3, "( handle , ALEnum ) Use the alxGetSource* function to get the current value of a source parameter, as specified by ALEnum.\n"
  334. "Depending on the ALEnum you need to acquire, be sure to use the correct version (i.e. correct return type) of alxGetSource*.\n"
  335. "@param handle The ID (a non-negative integer) corresponding to a previously set up sound source.\n"
  336. "@param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.\n"
  337. "@return Returns current value of parameter specified by ALEnum for source identified by handle.\n"
  338. "@sa alxSource*, al*GetListener*")
  339. {
  340. ALenum e = getEnum(argv[2], (Source|Get|Int));
  341. if(e == AL_INVALID)
  342. {
  343. Con::errorf(ConsoleLogEntry::General, "cAudio_alxGetSourcei: invalid enum name '%s'", argv[2]);
  344. return(0);
  345. }
  346. S32 value;
  347. alxGetSourcei(dAtoi(argv[1]), e, &value);
  348. return(value);
  349. }
  350. //-----------------------------------------------
  351. ConsoleFunction(alxPlay, S32, 2, 2, "(audio-assetId) - Play the audio asset Id.\n"
  352. "@param audio-assetId The asset Id to play.\n"
  353. "@return The handle to the playing audio asset Id or 0 on error." )
  354. {
  355. // Fetch asset Id.
  356. const char* pAssetId = argv[1];
  357. // Acquire audio asset.
  358. AudioAsset* pAudioAsset = AssetDatabase.acquireAsset<AudioAsset>( pAssetId );
  359. // Did we get the audio asset?
  360. if ( pAudioAsset == NULL )
  361. {
  362. // No, so warn.
  363. Con::warnf( "alxPlay() - Could not find audio asset '%s'.", pAssetId );
  364. return NULL_AUDIOHANDLE;
  365. }
  366. // Fetch audio handle.
  367. AUDIOHANDLE handle = alxPlay( pAudioAsset );
  368. // Release asset.
  369. AssetDatabase.releaseAsset( pAssetId );
  370. return handle;
  371. }
  372. ConsoleFunction(alxPause, bool, 2, 2, "( handle ) Use the alxPause function to pause a currently playing sound as specified by handle.\n"
  373. "@param handle The ID (a non-negative integer) corresponding to a previously set up sound source.\n"
  374. "@return No return value.\n"
  375. "@sa alxIsPlaying, alxPlay, alxStopAll")
  376. {
  377. AUDIOHANDLE handle = dAtoi(argv[1]);
  378. if(handle == NULL_AUDIOHANDLE)
  379. return false;
  380. return alxPause( handle );
  381. }
  382. ConsoleFunction(alxUnpause, void, 2, 2, "( handle ) Use the alxUnpause function to resume playing a currently paused sound as specified by handle.\n"
  383. "@param handle The ID (a non-negative integer) corresponding to a previously set up sound source.\n"
  384. "@return No return value.\n"
  385. "@sa alxIsPlaying, alxPlay, alxStopAll")
  386. {
  387. AUDIOHANDLE handle = dAtoi(argv[1]);
  388. if(handle == NULL_AUDIOHANDLE)
  389. return;
  390. alxUnPause( handle );
  391. }
  392. //-----------------------------------------------
  393. ConsoleFunction(alxStop, void, 2, 2, "( handle ) Use the alxStop function to stop a currently playing sound as specified by handle.\n"
  394. "@param handle The ID (a non-negative integer) corresponding to a previously set up sound source.\n"
  395. "@return No return value.\n"
  396. "@sa alxIsPlaying, alxPlay, alxStopAll")
  397. {
  398. AUDIOHANDLE handle = dAtoi(argv[1]);
  399. if(handle == NULL_AUDIOHANDLE)
  400. return;
  401. alxStop(handle);
  402. }
  403. //-----------------------------------------------
  404. ConsoleFunction(alxStopAll, void, 1, 1, "() Use the alxStopAll function to stop all currently playing sounds associated with registered handles.\n"
  405. "@return No return.\n"
  406. "@sa alxIsPlaying, alxPlay, alxStop")
  407. {
  408. alxStopAll();
  409. }
  410. //-----------------------------------------------
  411. ConsoleFunction(alxIsPlaying, bool, 2, 5, "( handle ) Use the alxIsPlaying function to determine if the sound associated with a previously set-up sound handle is playing or not.\n"
  412. "@param handle The ID (a non-negative integer) corresponding to a previously set up sound source.\n"
  413. "@return Returns 1 if specified handle is being played, 0 otherwise.\n"
  414. "@sa alxPlay, alxStop, alxStopAll")
  415. {
  416. AUDIOHANDLE handle = dAtoi(argv[1]);
  417. if(handle == NULL_AUDIOHANDLE)
  418. return false;
  419. return alxIsPlaying(handle);
  420. }
  421. //--------------------------------------------------------------------------
  422. // Listener
  423. //--------------------------------------------------------------------------
  424. ConsoleFunction(alxListenerf, void, 3, 3, "( AlEnum , value ) Use the al*Listener* function to set a listener parameter(s) as specified by the OpenAL enumerated type ALEnum.\n"
  425. "@param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.\n"
  426. "@param value An ALEnum type specific value corresponding to the new value for this enumerated parameters.\n"
  427. "@return No return value.\n"
  428. "@sa al*GetListener*, alxSource*")
  429. {
  430. ALenum e = getEnum(argv[1], (Listener|Set|Float));
  431. if(e == AL_INVALID)
  432. {
  433. Con::errorf(ConsoleLogEntry::General, "alxListenerf: invalid enum name '%s'", argv[1]);
  434. return;
  435. }
  436. alxListenerf(e, dAtof(argv[2]));
  437. }
  438. //-----------------------------------------------
  439. ConsoleFunction(alListener3f, void, 3, 5, "( ALEnum , x , y , z) Use the al*Listener* function to set a listener parameter(s) as specified by the OpenAL enumerated type ALEnum.\n"
  440. "@param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.\n"
  441. "@param x,y,z XYZ floating-point coordinates.\n"
  442. "@return No return value.\n"
  443. "@sa al*GetListener*, alxSource*")
  444. {
  445. ALenum e = getEnum(argv[1], (Listener|Set|Float3));
  446. if(e == AL_INVALID)
  447. {
  448. Con::errorf(ConsoleLogEntry::General, "alListener3f: invalid enum name '%s'", argv[1]);
  449. return;
  450. }
  451. if(argc != 3 && argc != 5)
  452. {
  453. Con::errorf(ConsoleLogEntry::General, "alListener3f: wrong number of arguments");
  454. return;
  455. }
  456. Point3F pos;
  457. if(argc == 3)
  458. dSscanf(argv[2], "%g %g %g", &pos.x, &pos.y, &pos.z);
  459. else
  460. {
  461. pos.x = dAtof(argv[2]);
  462. pos.y = dAtof(argv[3]);
  463. pos.z = dAtof(argv[4]);
  464. }
  465. alListener3f(e, pos.x, pos.y, pos.z);
  466. }
  467. //-----------------------------------------------
  468. ConsoleFunction(alxGetListenerf, F32, 2, 2, "( ALEnum ) Use the al*GetListener* function to get the current value of a listener parameter, as specified by ALEnum.\n"
  469. "Depending on the ALEnum you need to acquire, be sure to use the correct version (i.e. correct return type) of al*GetListener*.\n"
  470. "@param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.\n"
  471. "@return Returns a float (alxGetListenerf), a vector of three floats (alGetListener3f), or an integer value respectively (alGetListeneri).\n"
  472. "@sa alxGetSource*")
  473. {
  474. ALenum e = getEnum(argv[1], (Source|Get|Float));
  475. if(e == AL_INVALID)
  476. {
  477. Con::errorf(ConsoleLogEntry::General, "alxGetListenerf: invalid enum name '%s'", argv[1]);
  478. return(0.f);
  479. }
  480. F32 value;
  481. alxGetListenerf(e, &value);
  482. return(value);
  483. }
  484. //-----------------------------------------------
  485. ConsoleFunction(alGetListener3f, const char *, 2, 2, "( ALEnum ) Use the al*GetListener* function to get the current value of a listener parameter, as specified by ALEnum.\n"
  486. "Depending on the ALEnum you need to acquire, be sure to use the correct version (i.e. correct return type) of al*GetListener*.\n"
  487. "@param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.\n"
  488. "@return Returns a float (alxGetListenerf), a vector of three floats (alGetListener3f), or an integer value respectively (alGetListeneri).\n"
  489. "@sa alxGetSource*")
  490. {
  491. ALenum e = getEnum(argv[2], (Source|Get|Float));
  492. if(e == AL_INVALID)
  493. {
  494. Con::errorf(ConsoleLogEntry::General, "alGetListener3f: invalid enum name '%s'", argv[1]);
  495. return("0 0 0");
  496. }
  497. F32 value1, value2, value3;
  498. alGetListener3f(e, &value1, &value2, &value3);
  499. char * ret = Con::getReturnBuffer(64);
  500. dSprintf(ret, 64, "%7.3f %7.3 %7.3", value1, value2, value3);
  501. return(ret);
  502. }
  503. //-----------------------------------------------
  504. ConsoleFunction(alGetListeneri, S32, 2, 2, "( ALEnum ) Use the al*GetListener* function to get the current value of a listener parameter, as specified by ALEnum.\n"
  505. "Depending on the ALEnum you need to acquire, be sure to use the correct version (i.e. correct return type) of al*GetListener*.\n"
  506. "@param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.\n"
  507. "@return Returns a float (alxGetListenerf), a vector of three floats (alGetListener3f), or an integer value respectively (alGetListeneri).\n"
  508. "@sa alxGetSource*")
  509. {
  510. ALenum e = getEnum(argv[1], (Source|Get|Int));
  511. if(e == AL_INVALID)
  512. {
  513. Con::errorf(ConsoleLogEntry::General, "alGetListeneri: invalid enum name '%s'", argv[1]);
  514. return(0);
  515. }
  516. S32 value;
  517. alGetListeneri(e, &value);
  518. return(value);
  519. }
  520. //--------------------------------------------------------------------------
  521. // Channel Volumes
  522. //--------------------------------------------------------------------------
  523. ConsoleFunction(alxGetChannelVolume, F32, 2, 2, "( channelID ) Use the alxGetChannelVolume function to get the volume setting for a specified channel.\n"
  524. "@param channelID An integer value, equal to or greater than 0, corresponding to a valid audio channel.\n"
  525. "@return Returns volume [ 0.0, 1.0 ] for channel specified by channelID.\n"
  526. "@sa alxSetChannelVolume")
  527. {
  528. U32 channel = dAtoi(argv[1]);
  529. if(channel >= Audio::AudioVolumeChannels)
  530. {
  531. Con::errorf(ConsoleLogEntry::General, "alxGetChannelVolume: invalid channel '%d'", dAtoi(argv[1]));
  532. return(0.f);
  533. }
  534. return(mAudioChannelVolumes[channel]);
  535. }
  536. //-----------------------------------------------
  537. ConsoleFunction(alxSetChannelVolume, bool, 3, 3, "( channelD , volume ) Use the alxSetChannelVolume function to set a volume [ 0.0, 1.0 ] for the channel specified by channelID.\n"
  538. "@param channelID An integer value, equal to or greater than 0, corresponding to a valid audio channel.\n"
  539. "@param volume A value between 0.0 and 1.0 specifying the new volume for the specified channel.\n"
  540. "@return Returns true on success and false on failure.\n"
  541. "@sa alxGetChannelVolume")
  542. {
  543. U32 channel = dAtoi(argv[1]);
  544. F32 volume = mClampF(dAtof(argv[2]), 0.f, 1.f);
  545. if(channel >= Audio::AudioVolumeChannels)
  546. {
  547. Con::errorf(ConsoleLogEntry::General, "alxSetChannelVolume: channel '%d' out of range [0, %d]", channel, Audio::AudioVolumeChannels);
  548. return false;
  549. }
  550. mAudioChannelVolumes[channel] = volume;
  551. alxUpdateTypeGain(channel);
  552. return true;
  553. }
  554. //-----------------------------------------------
  555. ConsoleFunction(alxGetStreamPosition, F32, 2, 2, "( handle ) Use the alxGetStreamPosition function to get the current play position for a playing sound. Note, this value is a percentage equivalent to the percent of the sound that as already played.\n"
  556. "@param handle The ID (a non-negative integer) corresponding to a previously set up sound source.\n"
  557. "@return Returns -1 for invalid handle, and 0.0 to 1.0 for valid handle indicating what percentage of the sound file has been played.\n"
  558. "@sa alxGetStreamDuration")
  559. {
  560. AUDIOHANDLE handle = dAtoi(argv[1]);
  561. if(handle == NULL_AUDIOHANDLE)
  562. return -1;
  563. return alxGetStreamPosition( handle );
  564. }
  565. //-----------------------------------------------
  566. ConsoleFunction(alxGetStreamDuration, F32, 2, 2, "( handle ) Use the alxGetStreamDuration function to determine the length of a previously set up sound in seconds.\n"
  567. "@param handle The ID (a non-negative integer) corresponding to a previously set up sound source.\n"
  568. "@return Returns -1 for invalid handle, and 0.0 to N.M for valid handle indicating length of scheduled sound in seconds.\n"
  569. "@sa alxGetStreamPosition")
  570. {
  571. AUDIOHANDLE handle = dAtoi(argv[1]);
  572. if(handle == NULL_AUDIOHANDLE)
  573. return -1;
  574. return alxGetStreamDuration( handle );
  575. }
  576. #ifdef TORQUE_OS_IOS
  577. ConsoleFunction(startiOSAudioStream, S32, 2, 2, "(audio-assetId) - Play the audio asset Id.\n"
  578. "@param audio-assetId The asset Id to play. This *must* be an MP3 to work correctly.\n"
  579. "@return The playing stream Id." )
  580. {
  581. // Fetch asset Id.
  582. const char* pAssetId = argv[1];
  583. // Acquire audio asset.
  584. AudioAsset* pAudioAsset = AssetDatabase.acquireAsset<AudioAsset>( pAssetId );
  585. // Did we get the audio asset?
  586. if ( pAudioAsset == NULL )
  587. {
  588. // No, so warn.
  589. Con::warnf( "startiOSAudioStream() - Could not find audio asset '%s'.", pAssetId );
  590. return 0;
  591. }
  592. // Fetch the audio filename,
  593. char fileName[1024];
  594. Con::expandPath( fileName, sizeof(fileName), pAudioAsset->getAudioFile() );
  595. iOSStreamSource* pStream = new iOSStreamSource( fileName );
  596. pStream->start( pAudioAsset->getLooping() );
  597. // Release asset.
  598. AssetDatabase.releaseAsset( pAssetId );
  599. return pStream->getId();
  600. }
  601. //-----------------------------------------------
  602. ConsoleFunction(stopiOSAudioStream, void, 2, 2, "( streamId ) - Stops playing the audio stream Id." )
  603. {
  604. SimObjectId streamId = dAtoi( argv[1] );
  605. iOSStreamSource* pStream = Sim::findObject<iOSStreamSource>( streamId );
  606. if( pStream != NULL )
  607. {
  608. if( pStream->isPlaying() )
  609. {
  610. pStream->stop();
  611. }
  612. pStream->deleteObject();
  613. }
  614. }
  615. ConsoleFunction(setiOSAudioStreamVolume, void, 3, 3, "setiPhoneAudioVolume( Stream ID, float volume )" )
  616. {
  617. SimObjectId streamId = dAtoi( argv[1] );
  618. iOSStreamSource* pStream = Sim::findObject<iOSStreamSource>( streamId );
  619. F32 volume = dAtof( argv[2] );
  620. if( pStream ) {
  621. if( pStream->isPlaying() ) {
  622. pStream->setVolume(volume);
  623. }
  624. }
  625. }
  626. #endif
  627. ConsoleFunctionGroupEnd(Audio);