wrap_Audio.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. /**
  2. * Copyright (c) 2006-2011 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. // LOVE
  21. #include "wrap_Audio.h"
  22. #include "openal/Audio.h"
  23. #include "null/Audio.h"
  24. #include <scripts/audio.lua.h>
  25. #include <common/runtime.h>
  26. namespace love
  27. {
  28. namespace audio
  29. {
  30. static Audio * instance = 0;
  31. int w_getNumSources(lua_State * L)
  32. {
  33. lua_pushinteger(L, instance->getNumSources());
  34. return 1;
  35. }
  36. int w_newSource1(lua_State * L)
  37. {
  38. Source * t = 0;
  39. if (luax_istype(L, 1, SOUND_SOUND_DATA_T))
  40. t = instance->newSource(luax_totype<love::sound::SoundData>(L, 1, "SoundData", SOUND_SOUND_DATA_T));
  41. else if (luax_istype(L, 1, SOUND_DECODER_T))
  42. t = instance->newSource(luax_totype<love::sound::Decoder>(L, 1, "Decoder", SOUND_DECODER_T));
  43. if (t)
  44. {
  45. luax_newtype(L, "Source", AUDIO_SOURCE_T, (void*)t);
  46. return 1;
  47. }
  48. else
  49. return luaL_error(L, "No matching overload");
  50. return 0;
  51. }
  52. int w_play(lua_State * L)
  53. {
  54. Source * s = luax_checksource(L, 1);
  55. instance->play(s);
  56. return 0;
  57. }
  58. int w_stop(lua_State * L)
  59. {
  60. if (lua_gettop(L) == 0)
  61. {
  62. instance->stop();
  63. }
  64. else
  65. {
  66. Source * s = luax_checksource(L, 1);
  67. s->stop();
  68. }
  69. return 0;
  70. }
  71. int w_pause(lua_State * L)
  72. {
  73. if (lua_gettop(L) == 0)
  74. {
  75. instance->pause();
  76. }
  77. else
  78. {
  79. Source * s = luax_checksource(L, 1);
  80. s->pause();
  81. }
  82. return 0;
  83. }
  84. int w_resume(lua_State * L)
  85. {
  86. if (lua_gettop(L) == 0)
  87. {
  88. instance->resume();
  89. }
  90. else
  91. {
  92. Source * s = luax_checksource(L, 1);
  93. s->resume();
  94. }
  95. return 0;
  96. }
  97. int w_rewind(lua_State * L)
  98. {
  99. if (lua_gettop(L) == 0)
  100. {
  101. instance->rewind();
  102. }
  103. else
  104. {
  105. Source * s = luax_checksource(L, 1);
  106. s->rewind();
  107. }
  108. return 0;
  109. }
  110. int w_setVolume(lua_State * L)
  111. {
  112. float v = (float)luaL_checknumber(L, 1);
  113. instance->setVolume(v);
  114. return 0;
  115. }
  116. int w_getVolume(lua_State * L)
  117. {
  118. lua_pushnumber(L, instance->getVolume());
  119. return 1;
  120. }
  121. int w_setPosition(lua_State * L)
  122. {
  123. float v[3];
  124. v[0] = (float)luaL_checknumber(L, 1);
  125. v[1] = (float)luaL_checknumber(L, 2);
  126. v[2] = (float)luaL_checknumber(L, 3);
  127. instance->setPosition(v);
  128. return 0;
  129. }
  130. int w_getPosition(lua_State * L)
  131. {
  132. float v[3];
  133. instance->getPosition(v);
  134. lua_pushnumber(L, v[0]);
  135. lua_pushnumber(L, v[1]);
  136. lua_pushnumber(L, v[2]);
  137. return 3;
  138. }
  139. int w_setOrientation(lua_State * L)
  140. {
  141. float v[6];
  142. v[0] = (float)luaL_checknumber(L, 1);
  143. v[1] = (float)luaL_checknumber(L, 2);
  144. v[2] = (float)luaL_checknumber(L, 3);
  145. v[3] = (float)luaL_checknumber(L, 4);
  146. v[4] = (float)luaL_checknumber(L, 5);
  147. v[5] = (float)luaL_checknumber(L, 6);
  148. instance->setOrientation(v);
  149. return 0;
  150. }
  151. int w_getOrientation(lua_State * L)
  152. {
  153. float v[6];
  154. instance->getOrientation(v);
  155. lua_pushnumber(L, v[0]);
  156. lua_pushnumber(L, v[1]);
  157. lua_pushnumber(L, v[2]);
  158. lua_pushnumber(L, v[3]);
  159. lua_pushnumber(L, v[4]);
  160. lua_pushnumber(L, v[5]);
  161. return 6;
  162. }
  163. int w_setVelocity(lua_State * L)
  164. {
  165. float v[3];
  166. v[0] = (float)luaL_checknumber(L, 1);
  167. v[1] = (float)luaL_checknumber(L, 2);
  168. v[2] = (float)luaL_checknumber(L, 3);
  169. instance->setVelocity(v);
  170. return 0;
  171. }
  172. int w_getVelocity(lua_State * L)
  173. {
  174. float v[3];
  175. instance->getVelocity(v);
  176. lua_pushnumber(L, v[0]);
  177. lua_pushnumber(L, v[1]);
  178. lua_pushnumber(L, v[2]);
  179. return 3;
  180. }
  181. int w_record(lua_State *)
  182. {
  183. instance->record();
  184. return 0;
  185. }
  186. int w_getRecordedData(lua_State * L)
  187. {
  188. love::sound::SoundData * sd = instance->getRecordedData();
  189. if (!sd)
  190. lua_pushnil(L);
  191. else
  192. luax_newtype(L, "SoundData", SOUND_SOUND_DATA_T, (void*)sd);
  193. return 1;
  194. }
  195. int w_stopRecording(lua_State * L)
  196. {
  197. if (luax_optboolean(L, 1, true))
  198. {
  199. love::sound::SoundData * sd = instance->stopRecording(true);
  200. if (!sd) lua_pushnil(L);
  201. else luax_newtype(L, "SoundData", SOUND_SOUND_DATA_T, (void*)sd);
  202. return 1;
  203. }
  204. instance->stopRecording(false);
  205. return 0;
  206. }
  207. int w_canRecord(lua_State * L) {
  208. luax_pushboolean(L, instance->canRecord());
  209. return 1;
  210. }
  211. int w_setDistanceModel(lua_State * L)
  212. {
  213. const char *modelStr = luaL_checkstring(L, 1);
  214. Audio::DistanceModel distanceModel;
  215. if (!Audio::getConstant(modelStr, distanceModel))
  216. return luaL_error(L, "Invalid distance model: %s", modelStr);
  217. instance->setDistanceModel(distanceModel);
  218. return 0;
  219. }
  220. int w_getDistanceModel(lua_State * L)
  221. {
  222. Audio::DistanceModel distanceModel = instance->getDistanceModel();
  223. const char *modelStr;
  224. if (!Audio::getConstant(distanceModel, modelStr))
  225. return 0;
  226. lua_pushstring(L, modelStr);
  227. return 1;
  228. }
  229. // List of functions to wrap.
  230. static const luaL_Reg functions[] = {
  231. { "getNumSources", w_getNumSources },
  232. { "newSource1", w_newSource1 },
  233. { "play", w_play },
  234. { "stop", w_stop },
  235. { "pause", w_pause },
  236. { "resume", w_resume },
  237. { "rewind", w_rewind },
  238. { "setVolume", w_setVolume },
  239. { "getVolume", w_getVolume },
  240. { "setPosition", w_setPosition },
  241. { "getPosition", w_getPosition },
  242. { "setOrientation", w_setOrientation },
  243. { "getOrientation", w_getOrientation },
  244. { "setVelocity", w_setVelocity },
  245. { "getVelocity", w_getVelocity },
  246. /*{ "record", w_record },
  247. { "getRecordedData", w_getRecordedData },
  248. { "stopRecording", w_stopRecording },*/
  249. { "setDistanceModel", w_setDistanceModel },
  250. { "getDistanceModel", w_getDistanceModel },
  251. { 0, 0 }
  252. };
  253. static const lua_CFunction types[] = {
  254. luaopen_source,
  255. 0
  256. };
  257. extern "C" int luaopen_love_audio(lua_State * L)
  258. {
  259. if (instance == 0)
  260. {
  261. // Try OpenAL first.
  262. try
  263. {
  264. instance = new love::audio::openal::Audio();
  265. }
  266. catch (love::Exception & e)
  267. {
  268. std::cout << e.what() << std::endl;
  269. }
  270. }
  271. else
  272. instance->retain();
  273. if (instance == 0)
  274. {
  275. // Fall back to nullaudio.
  276. try
  277. {
  278. instance = new love::audio::null::Audio();
  279. }
  280. catch (love::Exception & e)
  281. {
  282. std::cout << e.what() << std::endl;
  283. }
  284. }
  285. if (instance == 0)
  286. return luaL_error(L, "Could not open any audio module.");
  287. WrappedModule w;
  288. w.module = instance;
  289. w.name = "audio";
  290. w.flags = MODULE_T;
  291. w.functions = functions;
  292. w.types = types;
  293. int n = luax_register_module(L, w);
  294. if (luaL_loadbuffer(L, (const char *)audio_lua, sizeof(audio_lua), "audio.lua") == 0)
  295. lua_call(L, 0, 0);
  296. return n;
  297. }
  298. } // audio
  299. } // love