audio_ScriptBinding.cc 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  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_SAMPLE_OFFSET", AL_SAMPLE_OFFSET, (Source|Get|Set|Int) },
  83. { "AL_SEC_OFFSET", AL_SEC_OFFSET, (Source|Get|Set|Int) },
  84. { "AL_BYTE_OFFSET", AL_BYTE_OFFSET, (Source|Get|Set|Int) },
  85. //{ "AL_STREAMING", AL_STREAMING, (Source|Get|Set|Int) },
  86. //{ "AL_BUFFER", AL_BUFFER, (Source|Get|Set|Int) },
  87. { "AL_VENDOR", AL_VENDOR, (Context|Get) },
  88. { "AL_VERSION", AL_VERSION, (Context|Get) },
  89. { "AL_RENDERER", AL_RENDERER, (Context|Get) },
  90. { "AL_EXTENSIONS", AL_EXTENSIONS, (Context|Get) },
  91. /*
  92. // environment
  93. { "AL_ENV_ROOM_IASIG", AL_ENV_ROOM_IASIG, (Environment|Get|Set|Int) },
  94. { "AL_ENV_ROOM_HIGH_FREQUENCY_IASIG", AL_ENV_ROOM_HIGH_FREQUENCY_IASIG, (Environment|Get|Set|Int) },
  95. { "AL_ENV_REFLECTIONS_IASIG", AL_ENV_REFLECTIONS_IASIG, (Environment|Get|Set|Int) },
  96. { "AL_ENV_REVERB_IASIG", AL_ENV_REVERB_IASIG, (Environment|Get|Set|Int) },
  97. { "AL_ENV_ROOM_ROLLOFF_FACTOR_IASIG", AL_ENV_ROOM_ROLLOFF_FACTOR_IASIG, (Environment|Get|Set|Float) },
  98. { "AL_ENV_DECAY_TIME_IASIG", AL_ENV_DECAY_TIME_IASIG, (Environment|Get|Set|Float) },
  99. { "AL_ENV_DECAY_HIGH_FREQUENCY_RATIO_IASIG", AL_ENV_DECAY_HIGH_FREQUENCY_RATIO_IASIG, (Environment|Get|Set|Float) },
  100. { "AL_ENV_REFLECTIONS_DELAY_IASIG", AL_ENV_REFLECTIONS_DELAY_IASIG, (Environment|Get|Set|Float) },
  101. { "AL_ENV_REVERB_DELAY_IASIG", AL_ENV_REVERB_DELAY_IASIG, (Environment|Get|Set|Float) },
  102. { "AL_ENV_DIFFUSION_IASIG", AL_ENV_DIFFUSION_IASIG, (Environment|Get|Set|Float) },
  103. { "AL_ENV_DENSITY_IASIG", AL_ENV_DENSITY_IASIG, (Environment|Get|Set|Float) },
  104. { "AL_ENV_HIGH_FREQUENCY_REFERENCE_IASIG", AL_ENV_HIGH_FREQUENCY_REFERENCE_IASIG, (Environment|Get|Set|Float) },
  105. { "AL_ENV_ROOM_VOLUME_EXT", AL_ENV_ROOM_VOLUME_EXT, (Environment|Get|Set|Int) },
  106. { "AL_ENV_FLAGS_EXT", AL_ENV_FLAGS_EXT, (Environment|Get|Set|Int) },
  107. { "AL_ENV_EFFECT_VOLUME_EXT", AL_ENV_EFFECT_VOLUME_EXT, (Environment|Get|Set|Float) },
  108. { "AL_ENV_DAMPING_EXT", AL_ENV_DAMPING_EXT, (Environment|Get|Set|Float) },
  109. { "AL_ENV_ENVIRONMENT_SIZE_EXT", AL_ENV_ENVIRONMENT_SIZE_EXT, (Environment|Get|Set|Float) },
  110. // sample environment
  111. { "AL_ENV_SAMPLE_DIRECT_EXT", AL_ENV_SAMPLE_DIRECT_EXT, (Source|Get|Set|Int) },
  112. { "AL_ENV_SAMPLE_DIRECT_HF_EXT", AL_ENV_SAMPLE_DIRECT_HF_EXT, (Source|Get|Set|Int) },
  113. { "AL_ENV_SAMPLE_ROOM_EXT", AL_ENV_SAMPLE_ROOM_EXT, (Source|Get|Set|Int) },
  114. { "AL_ENV_SAMPLE_ROOM_HF_EXT", AL_ENV_SAMPLE_ROOM_HF_EXT, (Source|Get|Set|Int) },
  115. { "AL_ENV_SAMPLE_OUTSIDE_VOLUME_HF_EXT", AL_ENV_SAMPLE_OUTSIDE_VOLUME_HF_EXT, (Source|Get|Set|Int) },
  116. { "AL_ENV_SAMPLE_FLAGS_EXT", AL_ENV_SAMPLE_FLAGS_EXT, (Source|Get|Set|Int) },
  117. { "AL_ENV_SAMPLE_REVERB_MIX_EXT", AL_ENV_SAMPLE_REVERB_MIX_EXT, (Source|Get|Set|Float) },
  118. { "AL_ENV_SAMPLE_OBSTRUCTION_EXT", AL_ENV_SAMPLE_OBSTRUCTION_EXT, (Source|Get|Set|Float) },
  119. { "AL_ENV_SAMPLE_OBSTRUCTION_LF_RATIO_EXT", AL_ENV_SAMPLE_OBSTRUCTION_LF_RATIO_EXT, (Source|Get|Set|Float) },
  120. { "AL_ENV_SAMPLE_OCCLUSION_EXT", AL_ENV_SAMPLE_OCCLUSION_EXT, (Source|Get|Set|Float) },
  121. { "AL_ENV_SAMPLE_OCCLUSION_LF_RATIO_EXT", AL_ENV_SAMPLE_OCCLUSION_LF_RATIO_EXT, (Source|Get|Set|Float) },
  122. { "AL_ENV_SAMPLE_OCCLUSION_ROOM_RATIO_EXT", AL_ENV_SAMPLE_OCCLUSION_ROOM_RATIO_EXT, (Source|Get|Set|Float) },
  123. { "AL_ENV_SAMPLE_ROOM_ROLLOFF_EXT", AL_ENV_SAMPLE_ROOM_ROLLOFF_EXT, (Source|Get|Set|Float) },
  124. { "AL_ENV_SAMPLE_AIR_ABSORPTION_EXT", AL_ENV_SAMPLE_AIR_ABSORPTION_EXT, (Source|Get|Set|Float) },
  125. */
  126. };
  127. for(U32 i = 0; i < (sizeof(table) / sizeof(table[0])); i++)
  128. {
  129. if((table[i].mFlags & flags) != flags)
  130. continue;
  131. if(dStricmp(table[i].mName, name) == 0)
  132. return(table[i].mAlenum);
  133. }
  134. return(AL_INVALID);
  135. }
  136. //-----------------------------------------------
  137. ConsoleFunctionGroupBegin(Audio, "Functions dealing with the OpenAL audio layer.\n\n"
  138. "@see www.OpenAL.org for what these functions do. Variances from posted"
  139. " behaviour is described below.");
  140. /*! @defgroup AudioFunctions Audio
  141. @ingroup TorqueScriptFunctions
  142. @{
  143. */
  144. /*! Use the OpenALInitDriver function to initialize the OpenAL driver.
  145. This must be done before all other OpenAL operations.
  146. @return Returns true on successful initialization, false otherwise.
  147. @sa OpenALShutdownDriver
  148. */
  149. ConsoleFunctionWithDocs(OpenALInitDriver, ConsoleBool, 1, 1, ())
  150. {
  151. if (Audio::OpenALInit())
  152. {
  153. Con::printf(" OpenAL driver initialized successfully. Let's make some noise!");
  154. Con::printf("");
  155. static bool registered = false;
  156. if (!registered) {
  157. ResourceManager->registerExtension(".wav", AudioBuffer::construct);
  158. ResourceManager->registerExtension(".ogg", AudioBuffer::construct);
  159. }
  160. registered = true;
  161. return true;
  162. }
  163. Con::printf(" OpenAL driver failed to initialize... so quiet...");
  164. Con::printf("");
  165. return false;
  166. }
  167. //-----------------------------------------------
  168. /*! Use the OpenALShutdownDriver function to stop/shut down the OpenAL driver.
  169. After this is called, you must restart the driver with OpenALInitDriver to execute any new sound operations.
  170. @return No return value.
  171. @sa OpenALInitDriver
  172. */
  173. ConsoleFunctionWithDocs(OpenALShutdownDriver, ConsoleVoid, 1, 1, ())
  174. {
  175. Audio::OpenALShutdown();
  176. }
  177. //-----------------------------------------------
  178. /*!
  179. @note Currently does nothing (possibly deprecated)
  180. */
  181. ConsoleFunctionWithDocs(OpenALRegisterExtensions, ConsoleVoid, 1, 1, ())
  182. {
  183. }
  184. //-----------------------------------------------
  185. /*! Use the alGetString function to get the string equivalent to the specified OpenAL enumerated value.
  186. @param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.
  187. @return Returns a string corresponding to the passed ALEnum
  188. */
  189. ConsoleFunctionWithDocs(alGetString, ConsoleString, 2, 2, ( ALEnum ))
  190. {
  191. ALenum e = getEnum(argv[1], (Context|Get));
  192. if(e == AL_INVALID)
  193. {
  194. Con::errorf(ConsoleLogEntry::General, "alGetString: invalid enum name '%s'", argv[1]);
  195. return "";
  196. }
  197. return (const char*)alGetString(e);
  198. }
  199. //--------------------------------------------------------------------------
  200. // Soundfile
  201. //--------------------------------------------------------------------------
  202. /*! Use the alxGetAudioLength function to get the play-length of a specified resource sound file in milliseconds.
  203. @param audio-assetId The asset Id that specifies the audio file to check.
  204. @return Returns play-length of the audio file specified by audio-assetId in milliseconds.
  205. @sa alxGetStreamDuration, alxGetStreamPosition
  206. */
  207. ConsoleFunctionWithDocs(alxGetAudioLength, ConsoleInt, 2, 2, ( audio-assetId ))
  208. {
  209. // Fetch asset Id.
  210. const char* pAssetId = argv[1];
  211. // Acquire audio asset.
  212. AudioAsset* pAudioAsset = AssetDatabase.acquireAsset<AudioAsset>( pAssetId );
  213. // Did we get the audio asset?
  214. if ( pAudioAsset == NULL )
  215. {
  216. // No, so warn.
  217. Con::warnf( "alxGetAudioLength() - Could not find audio asset '%s'.", pAssetId );
  218. return 0;
  219. }
  220. Resource<AudioBuffer> buffer = AudioBuffer::find( pAudioAsset->getAudioFile() );
  221. if ( !buffer.isNull() )
  222. {
  223. ALuint alBuffer = buffer->getALBuffer();
  224. return alxGetWaveLen( alBuffer );
  225. }
  226. // Warn.
  227. Con::warnf( "alxGetAudioLength() - Could not find audio file '%s' for asset '%s'.", pAudioAsset->getAudioFile(), pAssetId );
  228. return 0;
  229. }
  230. //--------------------------------------------------------------------------
  231. // Source
  232. //--------------------------------------------------------------------------
  233. /*! Create a source from the specified asset Id.
  234. @param audio-assetId The asset Id to create the source from.
  235. @return The handle of the created source or 0 on error.
  236. */
  237. ConsoleFunctionWithDocs(alxCreateSource, ConsoleInt, 2, 2, (audio-assetId))
  238. {
  239. // Fetch asset Id.
  240. const char* pAssetId = argv[1];
  241. // Acquire audio asset.
  242. AudioAsset* pAudioAsset = AssetDatabase.acquireAsset<AudioAsset>( pAssetId );
  243. // Did we get the audio asset?
  244. if ( pAudioAsset == NULL )
  245. {
  246. // No, so warn.
  247. Con::warnf( "alxCreateSource() - Could not find audio asset '%s'.", pAssetId );
  248. return NULL_AUDIOHANDLE;
  249. }
  250. // Fetch audio handle.
  251. AUDIOHANDLE handle = alxCreateSource( pAudioAsset );
  252. // Release asset.
  253. AssetDatabase.releaseAsset( pAssetId );
  254. return handle;
  255. }
  256. //-----------------------------------------------
  257. /*! Use the alxSource* function to set a source parameter(s) as specified by the OpenAL enumerated type ALEnum.
  258. @param handle The ID (a non-negative integer) corresponding to a previously set up sound source.
  259. @param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.
  260. @param value An ALEnum type specific value corresponding to the new value for this enumerated parameters.
  261. @return No return value.
  262. @sa alxGetSource*, al*Listener*
  263. */
  264. ConsoleFunctionWithDocs(alxSourcef, ConsoleVoid, 4, 4, ( handle , ALEnum , value ))
  265. {
  266. ALenum e = getEnum(argv[2], (Source|Set|Float));
  267. if(e == AL_INVALID)
  268. {
  269. Con::errorf(ConsoleLogEntry::General, "cAudio_alxSourcef: invalid enum name '%s'", argv[2]);
  270. return;
  271. }
  272. alxSourcef(dAtoi(argv[1]), e, dAtof(argv[3]));
  273. }
  274. //-----------------------------------------------
  275. /*! Use the alxSource* function to set a source parameter(s) as specified by the OpenAL enumerated type ALEnum.
  276. @param handle The ID (a non-negative integer) corresponding to a previously set up sound source.
  277. @param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.
  278. @param x,y,z XYZ floating-point coordinates.
  279. @return No return value.
  280. @sa alxGetSource*, al*Listener*
  281. */
  282. ConsoleFunctionWithDocs(alxSource3f, ConsoleVoid, 3, 6, ( handle , ALEnum , x , y , z ))
  283. {
  284. ALenum e = getEnum(argv[2], (Source|Set|Float3));
  285. if(e == AL_INVALID)
  286. {
  287. Con::errorf(ConsoleLogEntry::General, "cAudio_alxSource3f: invalid enum name '%s'", argv[2]);
  288. return;
  289. }
  290. if((argc != 4 && argc != 6))
  291. {
  292. Con::errorf(ConsoleLogEntry::General, "cAudio_alxSource3f: wrong number of args");
  293. return;
  294. }
  295. Point3F pos;
  296. if(argc == 4)
  297. dSscanf(argv[3], "%g %g %g", &pos.x, &pos.y, &pos.z);
  298. else
  299. {
  300. pos.x = dAtof(argv[3]);
  301. pos.y = dAtof(argv[4]);
  302. pos.z = dAtof(argv[5]);
  303. }
  304. alxSource3f(dAtoi(argv[1]), e, pos.x, pos.y, pos.z);
  305. }
  306. //-----------------------------------------------
  307. /*! Use the alxSource* function to set a source parameter(s) as specified by the OpenAL enumerated type ALEnum.
  308. @param handle The ID (a non-negative integer) corresponding to a previously set up sound source.
  309. @param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.
  310. @param value An ALEnum type specific value corresponding to the new value for this enumerated parameters.
  311. @return No return value.
  312. @sa alxGetSource*, al*Listener*
  313. */
  314. ConsoleFunctionWithDocs(alxSourcei, ConsoleVoid, 4, 4, ( handle , ALEnum , value ))
  315. {
  316. ALenum e = getEnum(argv[2], (Source|Set|Int));
  317. if(e == AL_INVALID)
  318. {
  319. Con::errorf(ConsoleLogEntry::General, "cAudio_alxSourcei: invalid enum name '%s'", argv[2]);
  320. return;
  321. }
  322. alxSourcei(dAtoi(argv[1]), e, static_cast<ALint>(dAtoi(argv[3])));
  323. }
  324. //-----------------------------------------------
  325. /*! Use the alxGetSource* function to get the current value of a source parameter, as specified by ALEnum.
  326. Depending on the ALEnum you need to acquire, be sure to use the correct version (i.e. correct return type) of alxGetSource*.
  327. @param handle The ID (a non-negative integer) corresponding to a previously set up sound source.
  328. @param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.
  329. @return Returns current value of parameter specified by ALEnum for source identified by handle.
  330. @sa alxSource*, al*GetListener*
  331. */
  332. ConsoleFunctionWithDocs(alxGetSourcef, ConsoleFloat, 3, 3, ( handle , ALEnum ))
  333. {
  334. ALenum e = getEnum(argv[2], (Source|Get|Float));
  335. if(e == AL_INVALID)
  336. {
  337. Con::errorf(ConsoleLogEntry::General, "cAudio_alxGetSourcef: invalid enum name '%s'", argv[2]);
  338. return(0.f);
  339. }
  340. F32 value;
  341. alxGetSourcef(dAtoi(argv[1]), e, &value);
  342. return(value);
  343. }
  344. //-----------------------------------------------
  345. /*! Use the alxGetSource* function to get the current value of a source parameter, as specified by ALEnum.
  346. Depending on the ALEnum you need to acquire, be sure to use the correct version (i.e. correct return type) of alxGetSource*.
  347. @param handle The ID (a non-negative integer) corresponding to a previously set up sound source.
  348. @param ALEnum A string containing an OpenAL enumerated type name.
  349. @return Returns current value of parameter specified by ALEnum for source identified by handle.
  350. @sa alxSource*, al*GetListener*
  351. */
  352. ConsoleFunctionWithDocs(alxGetSource3f, ConsoleString, 3, 3, ( handle , ALEnum ))
  353. {
  354. ALenum e = getEnum(argv[2], (Source|Get|Float3));
  355. if(e == AL_INVALID)
  356. {
  357. Con::errorf(ConsoleLogEntry::General, "cAudio_alxGetSource3f: invalid enum name '%s'", argv[2]);
  358. return("0 0 0");
  359. }
  360. F32 value1, value2, value3;
  361. alxGetSource3f(dAtoi(argv[1]), e, &value1, &value2, &value3);
  362. char * ret = Con::getReturnBuffer(64);
  363. dSprintf(ret, 64, "%7.3f %7.3 %7.3", value1, value2, value3);
  364. return(ret);
  365. }
  366. //-----------------------------------------------
  367. /*! Use the alxGetSource* function to get the current value of a source parameter, as specified by ALEnum.
  368. Depending on the ALEnum you need to acquire, be sure to use the correct version (i.e. correct return type) of alxGetSource*.
  369. @param handle The ID (a non-negative integer) corresponding to a previously set up sound source.
  370. @param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.
  371. @return Returns current value of parameter specified by ALEnum for source identified by handle.
  372. @sa alxSource*, al*GetListener*
  373. */
  374. ConsoleFunctionWithDocs(alxGetSourcei, ConsoleInt, 3, 3, ( handle , ALEnum ))
  375. {
  376. ALenum e = getEnum(argv[2], (Source|Get|Int));
  377. if(e == AL_INVALID)
  378. {
  379. Con::errorf(ConsoleLogEntry::General, "cAudio_alxGetSourcei: invalid enum name '%s'", argv[2]);
  380. return(0);
  381. }
  382. ALint value;
  383. alxGetSourcei(dAtoi(argv[1]), e, &value);
  384. return(static_cast<S32>(value));
  385. }
  386. //-----------------------------------------------
  387. /*! Play the audio asset Id.
  388. @param audio-assetId The asset Id to play.
  389. @return The handle to the playing audio asset Id or 0 on error.
  390. */
  391. ConsoleFunctionWithDocs(alxPlay, ConsoleInt, 2, 2, (audio-assetId))
  392. {
  393. // Fetch asset Id.
  394. const char* pAssetId = argv[1];
  395. // Acquire audio asset.
  396. AudioAsset* pAudioAsset = AssetDatabase.acquireAsset<AudioAsset>( pAssetId );
  397. // Did we get the audio asset?
  398. if ( pAudioAsset == NULL )
  399. {
  400. // No, so warn.
  401. Con::warnf( "alxPlay() - Could not find audio asset '%s'.", pAssetId );
  402. return NULL_AUDIOHANDLE;
  403. }
  404. // Fetch audio handle.
  405. AUDIOHANDLE handle = alxPlay( pAudioAsset );
  406. // Release asset.
  407. AssetDatabase.releaseAsset( pAssetId );
  408. return handle;
  409. }
  410. /*! Use the alxPause function to pause a currently playing sound as specified by handle.
  411. @param handle The ID (a non-negative integer) corresponding to a previously set up sound source.
  412. @return No return value.
  413. @sa alxIsPlaying, alxPlay, alxStopAll
  414. */
  415. ConsoleFunctionWithDocs(alxPause, ConsoleBool, 2, 2, ( handle ))
  416. {
  417. AUDIOHANDLE handle = dAtoi(argv[1]);
  418. if(handle == NULL_AUDIOHANDLE)
  419. return false;
  420. return alxPause( handle );
  421. }
  422. /*! Use the alxUnpause function to resume playing a currently paused sound as specified by handle.
  423. @param handle The ID (a non-negative integer) corresponding to a previously set up sound source.
  424. @return No return value.
  425. @sa alxIsPlaying, alxPlay, alxStopAll
  426. */
  427. ConsoleFunctionWithDocs(alxUnpause, ConsoleVoid, 2, 2, ( handle ))
  428. {
  429. AUDIOHANDLE handle = dAtoi(argv[1]);
  430. if(handle == NULL_AUDIOHANDLE)
  431. return;
  432. alxUnPause( handle );
  433. }
  434. //-----------------------------------------------
  435. /*! Use the alxStop function to stop a currently playing sound as specified by handle.
  436. @param handle The ID (a non-negative integer) corresponding to a previously set up sound source.
  437. @return No return value.
  438. @sa alxIsPlaying, alxPlay, alxStopAll
  439. */
  440. ConsoleFunctionWithDocs(alxStop, ConsoleVoid, 2, 2, ( handle ))
  441. {
  442. AUDIOHANDLE handle = dAtoi(argv[1]);
  443. if(handle == NULL_AUDIOHANDLE)
  444. return;
  445. alxStop(handle);
  446. }
  447. //-----------------------------------------------
  448. /*! Use the alxStopAll function to stop all currently playing sounds associated with registered handles.
  449. @return No return.
  450. @sa alxIsPlaying, alxPlay, alxStop
  451. */
  452. ConsoleFunctionWithDocs(alxStopAll, ConsoleVoid, 1, 1, ())
  453. {
  454. alxStopAll();
  455. }
  456. //-----------------------------------------------
  457. /*! Use the alxIsPlaying function to determine if the sound associated with a previously set-up sound handle is playing or not.
  458. @param handle The ID (a non-negative integer) corresponding to a previously set up sound source.
  459. @return Returns 1 if specified handle is being played, 0 otherwise.
  460. @sa alxPlay, alxStop, alxStopAll
  461. */
  462. ConsoleFunctionWithDocs(alxIsPlaying, ConsoleBool, 2, 5, ( handle ))
  463. {
  464. AUDIOHANDLE handle = dAtoi(argv[1]);
  465. if(handle == NULL_AUDIOHANDLE)
  466. return false;
  467. return alxIsPlaying(handle);
  468. }
  469. //--------------------------------------------------------------------------
  470. // Listener
  471. //--------------------------------------------------------------------------
  472. /*! Use the al*Listener* function to set a listener parameter(s) as specified by the OpenAL enumerated type ALEnum.
  473. @param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.
  474. @param value An ALEnum type specific value corresponding to the new value for this enumerated parameters.
  475. @return No return value.
  476. @sa al*GetListener*, alxSource*
  477. */
  478. ConsoleFunctionWithDocs(alxListenerf, ConsoleVoid, 3, 3, ( AlEnum , value ))
  479. {
  480. ALenum e = getEnum(argv[1], (Listener|Set|Float));
  481. if(e == AL_INVALID)
  482. {
  483. Con::errorf(ConsoleLogEntry::General, "alxListenerf: invalid enum name '%s'", argv[1]);
  484. return;
  485. }
  486. alxListenerf(e, dAtof(argv[2]));
  487. }
  488. //-----------------------------------------------
  489. /*! Use the al*Listener* function to set a listener parameter(s) as specified by the OpenAL enumerated type ALEnum.
  490. @param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.
  491. @param x,y,z XYZ floating-point coordinates.
  492. @return No return value.
  493. @sa al*GetListener*, alxSource*
  494. */
  495. ConsoleFunctionWithDocs(alListener3f, ConsoleVoid, 3, 5, ( ALEnum , x , y , z))
  496. {
  497. ALenum e = getEnum(argv[1], (Listener|Set|Float3));
  498. if(e == AL_INVALID)
  499. {
  500. Con::errorf(ConsoleLogEntry::General, "alListener3f: invalid enum name '%s'", argv[1]);
  501. return;
  502. }
  503. if(argc != 3 && argc != 5)
  504. {
  505. Con::errorf(ConsoleLogEntry::General, "alListener3f: wrong number of arguments");
  506. return;
  507. }
  508. Point3F pos;
  509. if(argc == 3)
  510. dSscanf(argv[2], "%g %g %g", &pos.x, &pos.y, &pos.z);
  511. else
  512. {
  513. pos.x = dAtof(argv[2]);
  514. pos.y = dAtof(argv[3]);
  515. pos.z = dAtof(argv[4]);
  516. }
  517. alxListenerPoint3F(e, &pos);
  518. }
  519. //-----------------------------------------------
  520. /*! Use the al*GetListener* function to get the current value of a listener parameter, as specified by ALEnum.
  521. Depending on the ALEnum you need to acquire, be sure to use the correct version (i.e. correct return type) of al*GetListener*.
  522. @param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.
  523. @return Returns a float (alxGetListenerf), a vector of three floats (alGetListener3f), or an integer value respectively (alGetListeneri).
  524. @sa alxGetSource*
  525. */
  526. ConsoleFunctionWithDocs(alxGetListenerf, ConsoleFloat, 2, 2, ( ALEnum ))
  527. {
  528. ALenum e = getEnum(argv[1], (Source|Get|Float));
  529. if(e == AL_INVALID)
  530. {
  531. Con::errorf(ConsoleLogEntry::General, "alxGetListenerf: invalid enum name '%s'", argv[1]);
  532. return(0.f);
  533. }
  534. F32 value;
  535. alxGetListenerf(e, &value);
  536. return(value);
  537. }
  538. //-----------------------------------------------
  539. /*! Use the al*GetListener* function to get the current value of a listener parameter, as specified by ALEnum.
  540. Depending on the ALEnum you need to acquire, be sure to use the correct version (i.e. correct return type) of al*GetListener*.
  541. @param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.
  542. @return Returns a float (alxGetListenerf), a vector of three floats (alGetListener3f), or an integer value respectively (alGetListeneri).
  543. @sa alxGetSource*
  544. */
  545. ConsoleFunctionWithDocs(alGetListener3f, ConsoleString, 2, 2, ( ALEnum ))
  546. {
  547. ALenum e = getEnum(argv[1], (Source|Get|Float3));
  548. if(e == AL_INVALID)
  549. {
  550. Con::errorf(ConsoleLogEntry::General, "alGetListener3f: invalid enum name '%s'", argv[1]);
  551. return("0 0 0");
  552. }
  553. Point3F v;
  554. alxGetListenerPoint3F(e, &v);
  555. char * ret = Con::getReturnBuffer(64);
  556. dSprintf(ret, 64, "%7.3f %7.3f %7.3f", v.x, v.y, v.z);
  557. return(ret);
  558. }
  559. //-----------------------------------------------
  560. /*! Use the al*GetListener* function to get the current value of a listener parameter, as specified by ALEnum.
  561. Depending on the ALEnum you need to acquire, be sure to use the correct version (i.e. correct return type) of al*GetListener*.
  562. @param ALEnum A string containing an OpenAL enumerated type name. See (above) table of ALEnum values for legal values.
  563. @return Returns a float (alxGetListenerf), a vector of three floats (alGetListener3f), or an integer value respectively (alGetListeneri).
  564. @sa alxGetSource*
  565. */
  566. ConsoleFunctionWithDocs(alGetListeneri, ConsoleInt, 2, 2, ( ALEnum ))
  567. {
  568. ALenum e = getEnum(argv[1], (Source|Get|Int));
  569. if(e == AL_INVALID)
  570. {
  571. Con::errorf(ConsoleLogEntry::General, "alGetListeneri: invalid enum name '%s'", argv[1]);
  572. return(0);
  573. }
  574. S32 value;
  575. alGetListeneri(e, &value);
  576. return(value);
  577. }
  578. //--------------------------------------------------------------------------
  579. // Channel Volumes
  580. //--------------------------------------------------------------------------
  581. /*! Use the alxGetChannelVolume function to get the volume setting for a specified channel.
  582. @param channelID An integer value, equal to or greater than 0, corresponding to a valid audio channel.
  583. @return Returns volume [ 0.0, 1.0 ] for channel specified by channelID.
  584. @sa alxSetChannelVolume
  585. */
  586. ConsoleFunctionWithDocs(alxGetChannelVolume, ConsoleFloat, 2, 2, ( channelID ))
  587. {
  588. U32 channel = dAtoi(argv[1]);
  589. if(channel >= Audio::AudioVolumeChannels)
  590. {
  591. Con::errorf(ConsoleLogEntry::General, "alxGetChannelVolume: invalid channel '%d'", dAtoi(argv[1]));
  592. return(0.f);
  593. }
  594. return(mAudioChannelVolumes[channel]);
  595. }
  596. //-----------------------------------------------
  597. /*! Use the alxSetChannelVolume function to set a volume [ 0.0, 1.0 ] for the channel specified by channelID.
  598. @param channelID An integer value, equal to or greater than 0, corresponding to a valid audio channel.
  599. @param volume A value between 0.0 and 1.0 specifying the new volume for the specified channel.
  600. @return Returns true on success and false on failure.
  601. @sa alxGetChannelVolume
  602. */
  603. ConsoleFunctionWithDocs(alxSetChannelVolume, ConsoleBool, 3, 3, ( channelD , volume ))
  604. {
  605. U32 channel = dAtoi(argv[1]);
  606. F32 volume = mClampF(dAtof(argv[2]), 0.f, 1.f);
  607. if(channel >= Audio::AudioVolumeChannels)
  608. {
  609. Con::errorf(ConsoleLogEntry::General, "alxSetChannelVolume: channel '%d' out of range [0, %d]", channel, Audio::AudioVolumeChannels);
  610. return false;
  611. }
  612. mAudioChannelVolumes[channel] = volume;
  613. alxUpdateTypeGain(channel);
  614. return true;
  615. }
  616. //-----------------------------------------------
  617. /*! 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.
  618. @param handle The ID (a non-negative integer) corresponding to a previously set up sound source.
  619. @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.
  620. @sa alxGetStreamDuration
  621. */
  622. ConsoleFunctionWithDocs(alxGetStreamPosition, ConsoleFloat, 2, 2, ( handle ))
  623. {
  624. AUDIOHANDLE handle = dAtoi(argv[1]);
  625. if(handle == NULL_AUDIOHANDLE)
  626. return -1;
  627. return alxGetStreamPosition( handle );
  628. }
  629. //-----------------------------------------------
  630. /*! Use the alxGetStreamDuration function to determine the length of a previously set up sound in seconds.
  631. @param handle The ID (a non-negative integer) corresponding to a previously set up sound source.
  632. @return Returns -1 for invalid handle, and 0.0 to N.M for valid handle indicating length of scheduled sound in seconds.
  633. @sa alxGetStreamPosition
  634. */
  635. ConsoleFunctionWithDocs(alxGetStreamDuration, ConsoleFloat, 2, 2, ( handle ))
  636. {
  637. AUDIOHANDLE handle = dAtoi(argv[1]);
  638. if(handle == NULL_AUDIOHANDLE)
  639. return -1;
  640. return alxGetStreamDuration( handle );
  641. }
  642. #ifdef TORQUE_OS_IOS
  643. /*! Play the audio asset Id.
  644. @param audio-assetId The asset Id to play. This *must* be an MP3 to work correctly.
  645. @return The playing stream Id.
  646. */
  647. ConsoleFunctionWithDocs(startiOSAudioStream, ConsoleInt, 2, 2, (audio-assetId))
  648. {
  649. // Fetch asset Id.
  650. const char* pAssetId = argv[1];
  651. // Acquire audio asset.
  652. AudioAsset* pAudioAsset = AssetDatabase.acquireAsset<AudioAsset>( pAssetId );
  653. // Did we get the audio asset?
  654. if ( pAudioAsset == NULL )
  655. {
  656. // No, so warn.
  657. Con::warnf( "startiOSAudioStream() - Could not find audio asset '%s'.", pAssetId );
  658. return 0;
  659. }
  660. // Fetch the audio filename,
  661. char fileName[1024];
  662. Con::expandPath( fileName, sizeof(fileName), pAudioAsset->getAudioFile() );
  663. iOSStreamSource* pStream = new iOSStreamSource( fileName );
  664. pStream->start( pAudioAsset->getLooping() );
  665. // Release asset.
  666. AssetDatabase.releaseAsset( pAssetId );
  667. return pStream->getId();
  668. }
  669. //-----------------------------------------------
  670. /*! Stops playing the audio stream Id.
  671. */
  672. ConsoleFunctionWithDocs(stopiOSAudioStream, ConsoleVoid, 2, 2, ( streamId ))
  673. {
  674. SimObjectId streamId = dAtoi( argv[1] );
  675. iOSStreamSource* pStream = Sim::findObject<iOSStreamSource>( streamId );
  676. if( pStream != NULL )
  677. {
  678. if( pStream->isPlaying() )
  679. {
  680. pStream->stop();
  681. }
  682. pStream->deleteObject();
  683. }
  684. }
  685. /*!
  686. */
  687. ConsoleFunctionWithDocs(setiOSAudioStreamVolume, ConsoleVoid, 3, 3, setiPhoneAudioVolume( Stream ID, float volume ))
  688. {
  689. SimObjectId streamId = dAtoi( argv[1] );
  690. iOSStreamSource* pStream = Sim::findObject<iOSStreamSource>( streamId );
  691. F32 volume = dAtof( argv[2] );
  692. if( pStream ) {
  693. if( pStream->isPlaying() ) {
  694. pStream->setVolume(volume);
  695. }
  696. }
  697. }
  698. #endif
  699. /*! @} */ // group AudioFunctions