Python1320

Untitled

Dec 7th, 2010
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.01 KB | None | 0 0
  1. #define _RETAIL
  2. #include "GMLuaModule.h"
  3. #include "gm_bass.h"
  4.  
  5. #include "memdbgon.h"
  6.  
  7. #define META_CHANNEL "BASSChannel"
  8. #define TYPE_CHANNEL 6667
  9.  
  10. #define CHANNELFROMLUA() ILuaInterface *gLua = Lua(); \
  11.                             if (gLua->GetType(1) != TYPE_CHANNEL) gLua->TypeError(META_CHANNEL, 1); \
  12.                             DWORD handle = (DWORD)gLua->GetUserData(1);
  13.  
  14. #define TIME2LUA(X)     QWORD len = X(handle, BASS_POS_BYTE); \
  15.                     float time = (float)BASS_ChannelBytes2Seconds(handle, len); \
  16.                     gLua->Push(time);
  17.  
  18. #define LUA2TIME(X) QWORD pos = BASS_ChannelSeconds2Bytes(handle, X);
  19.  
  20. volatile int numThreads = 0;
  21.  
  22. struct streamProcData
  23. {
  24.     char *file;
  25.     int callback;
  26.     double offset;
  27.     DWORD handle;
  28.     int error;
  29.     SyncList<streamProcData *>* pending;
  30. };
  31.  
  32. SyncList<streamProcData *>* GetPendingChannels( ILuaInterface *gLua )
  33. {
  34.     ILuaObject* bass = gLua->GetGlobal( "BASS" );
  35.     if (!bass) return NULL;
  36.  
  37.     SyncList<streamProcData *>* pData = (SyncList<streamProcData *>*)bass->GetMemberUserDataLite( "p_PendingChannels" );
  38.     return pData;
  39. }
  40.  
  41. LUA_FUNCTION(channel_gc)
  42. {
  43.     CHANNELFROMLUA()
  44.  
  45.     BASS_StreamFree(handle);
  46.     return 0;
  47. }
  48.  
  49. LUA_FUNCTION(channel_play)
  50. {
  51.     CHANNELFROMLUA()
  52.     BASS_ChannelPlay(handle, true);
  53.     return 0;
  54. }
  55.  
  56. LUA_FUNCTION(channel_pause)
  57. {
  58.     CHANNELFROMLUA()
  59.  
  60.     BASS_ChannelPause(handle);
  61.     return 0;
  62. }
  63.  
  64. LUA_FUNCTION(channel_stop)
  65. {
  66.     CHANNELFROMLUA()
  67.  
  68.     BASS_ChannelStop(handle);
  69.     return 0;
  70. }
  71.  
  72. LUA_FUNCTION(channel_getlength)
  73. {
  74.     CHANNELFROMLUA()
  75.  
  76.     TIME2LUA(BASS_ChannelGetLength)
  77.     return 1;
  78. }
  79.  
  80. LUA_FUNCTION(channel_getposition)
  81. {
  82.     CHANNELFROMLUA()
  83.  
  84.     TIME2LUA(BASS_ChannelGetPosition)
  85.     return 1;
  86. }
  87.  
  88. LUA_FUNCTION(channel_getplaying)
  89. {
  90.     CHANNELFROMLUA()
  91.  
  92.     gLua->Push((bool)(BASS_ChannelIsActive(handle) == BASS_ACTIVE_PLAYING));
  93.     return 1;
  94. }
  95.  
  96. LUA_FUNCTION(channel_getlevel)
  97. {
  98.     CHANNELFROMLUA()
  99.  
  100.     DWORD level = BASS_ChannelGetLevel(handle);
  101.     gLua->Push((float)HIWORD(level));
  102.     gLua->Push((float)LOWORD(level));
  103.     return 2;
  104. }
  105.  
  106. LUA_FUNCTION(channel_fft2048)
  107. {
  108.     CHANNELFROMLUA()
  109.  
  110.     float fft[1024];
  111.     BASS_ChannelGetData(handle,fft,BASS_DATA_FFT2048);
  112.     ILuaObject *tbl = gLua->GetNewTable();
  113.     for(int x = 0; x < 1024; x++)
  114.     {
  115.         tbl->SetMember((float)x+1,fft[x]);
  116.     }
  117.     gLua->Push(tbl);
  118.     tbl->UnReference();
  119.     return 1;
  120. }
  121.  
  122. LUA_FUNCTION(channel_getrawtag)
  123. {
  124.     CHANNELFROMLUA()
  125.  
  126.     gLua->CheckType(2, GLua::TYPE_NUMBER);
  127.     int tag = gLua->GetInteger(2);
  128.  
  129.     const char *buff = BASS_ChannelGetTags(handle,tag);
  130.     gLua->Push(buff);
  131.     return 1;
  132. }
  133.  
  134. LUA_FUNCTION(channel_gettag)
  135. {
  136.     CHANNELFROMLUA()
  137.  
  138.     gLua->CheckType(2, GLua::TYPE_STRING);
  139.     const char *format = gLua->GetString(2);
  140.  
  141.     const char *buff = TAGS_Read(handle, format);
  142.     gLua->Push(buff);
  143.     return 1;
  144. }
  145.  
  146. LUA_FUNCTION(channel_setposition)
  147. {
  148.     CHANNELFROMLUA()
  149.  
  150.     gLua->CheckType(2, GLua::TYPE_NUMBER);
  151.  
  152.     LUA2TIME(gLua->GetDouble(2));
  153.     BASS_ChannelSetPosition(handle, pos, BASS_POS_BYTE);
  154.     return 0;
  155. }
  156.  
  157. LUA_FUNCTION(channel_setvolume)
  158. {
  159.     CHANNELFROMLUA()
  160.  
  161.     gLua->CheckType(2, GLua::TYPE_NUMBER);
  162.     double volume = gLua->GetDouble(2);
  163.  
  164.     BASS_ChannelSetAttribute(handle, BASS_ATTRIB_VOL, volume);
  165.  
  166.     return 0;
  167. }
  168.  
  169. BASS_3DVECTOR *Get3DVect(Vector *vect)
  170. {
  171.     BASS_3DVECTOR *vec = new BASS_3DVECTOR;
  172.     vec->x = vect->x;
  173.     vec->y = vect->y;
  174.     vec->z = vect->z;
  175.     return vec;
  176. }
  177.  
  178. LUA_FUNCTION(channel_set3dposition)
  179. {
  180.     CHANNELFROMLUA()
  181.  
  182.     gLua->CheckType(2, GLua::TYPE_VECTOR);
  183.     gLua->CheckType(3, GLua::TYPE_VECTOR);
  184.     gLua->CheckType(4, GLua::TYPE_VECTOR);
  185.     BASS_3DVECTOR *pos = Get3DVect((Vector *)gLua->GetUserData(2));
  186.     BASS_3DVECTOR *orient = Get3DVect((Vector *)gLua->GetUserData(3));
  187.     BASS_3DVECTOR *vel = Get3DVect((Vector *)gLua->GetUserData(4));
  188.  
  189.     BASS_ChannelSet3DAttributes(handle, BASS_3DMODE_NORMAL, 0, 0, 360, 360, 0);
  190.     BASS_ChannelSet3DPosition(handle, pos, orient, vel);
  191.  
  192.     BASS_Apply3D();
  193.  
  194.     delete pos;
  195.     delete orient;
  196.     delete vel;
  197.  
  198.     return 0;
  199. }
  200.  
  201. LUA_FUNCTION(bass_setposition)
  202. {
  203.     ILuaInterface *gLua = Lua();
  204.  
  205.     gLua->CheckType(1, GLua::TYPE_VECTOR);
  206.     gLua->CheckType(2, GLua::TYPE_VECTOR);
  207.     gLua->CheckType(3, GLua::TYPE_VECTOR);
  208.     gLua->CheckType(4, GLua::TYPE_VECTOR);
  209.  
  210.     BASS_3DVECTOR *pos = Get3DVect((Vector *)gLua->GetUserData(1));
  211.     BASS_3DVECTOR *vel = Get3DVect((Vector *)gLua->GetUserData(2));
  212.     BASS_3DVECTOR *front = Get3DVect((Vector *)gLua->GetUserData(3));
  213.     BASS_3DVECTOR *up = Get3DVect((Vector *)gLua->GetUserData(4));
  214.  
  215.     BASS_Set3DFactors(0.5, 0.01, -1.0);
  216.     BASS_Set3DPosition(pos, vel, front, up);
  217.  
  218.     BASS_Apply3D();
  219.  
  220.     delete pos;
  221.     delete vel;
  222.     delete front;
  223.     delete up;
  224.  
  225.     return 0;
  226. }
  227.  
  228. LUA_FUNCTION(bass_streamfile)
  229. {
  230.     ILuaInterface *gLua = Lua();
  231.     gLua->CheckType(1, GLua::TYPE_STRING);
  232.     const char *file = gLua->GetString(1);
  233.     char buff[1024];
  234.     _snprintf(buff, sizeof(buff), "garrysmod/sound/%s", file);
  235.  
  236.     DWORD handle = BASS_StreamCreateFile(false, buff, 0, 0, BASS_SAMPLE_MONO | BASS_SAMPLE_3D);
  237.  
  238.     ILuaObject* Channel = gLua->GetMetaTable(META_CHANNEL, TYPE_CHANNEL);
  239.     gLua->PushUserData(Channel, (void *)handle);
  240.     Channel->UnReference();
  241.     return 1;
  242. }
  243.  
  244. LUA_FUNCTION(bass_loadsample)
  245. {
  246.     ILuaInterface *gLua = Lua();
  247.     gLua->CheckType(1, GLua::TYPE_STRING);
  248.     gLua->CheckType(2, GLua::TYPE_NUMBER);
  249.     gLua->CheckType(3, GLua::TYPE_NUMBER);
  250.     gLua->CheckType(4, GLua::TYPE_NUMBER);
  251.     gLua->CheckType(5, GLua::TYPE_NUMBER);
  252.  
  253.     const char *path = gLua->GetString(1);
  254.     const char *base = "garrysmod/sound/";
  255.  
  256.     char filename[MAX_PATH] = {0};
  257.     strcat(filename, base);
  258.     strcat(filename, path);
  259.  
  260.     HSAMPLE sample = BASS_SampleLoad(true, (void*)filename, gLua->GetNumber(2), gLua->GetNumber(3), gLua->GetNumber(4), gLua->GetNumber(5));
  261.    
  262.     DWORD handle = BASS_SampleGetChannel(sample, false);
  263.  
  264.     ILuaObject* Channel = gLua->GetMetaTable(META_CHANNEL, TYPE_CHANNEL);
  265.     gLua->PushUserData(Channel, (void *)handle);
  266.     Channel->UnReference();
  267.     return 1;
  268. }
  269.  
  270. unsigned long WINAPI streamProc(void *param)
  271. {
  272.     streamProcData *data = (streamProcData *)param;
  273.     DWORD handle = BASS_StreamCreateURL(data->file, data->offset, BASS_STREAM_BLOCK | BASS_SAMPLE_MONO | BASS_SAMPLE_3D, NULL, 0);
  274.    
  275.     data->error = BASS_ErrorGetCode();
  276.     data->handle = handle;
  277.  
  278.     data->pending->add(data);
  279.  
  280.     numThreads--;
  281.     return 0;
  282. }
  283.  
  284. LUA_FUNCTION(bass_streamfileurl)
  285. {
  286.     ILuaInterface *gLua = Lua();
  287.     gLua->CheckType(1, GLua::TYPE_STRING);
  288.     gLua->CheckType(2, GLua::TYPE_NUMBER);
  289.     gLua->CheckType(3, GLua::TYPE_FUNCTION);
  290.  
  291.     char *file = strdup(gLua->GetString(1));
  292.     double time = gLua->GetDouble(2);
  293.     int callback = gLua->GetReference(3);
  294.  
  295.     streamProcData *data = new streamProcData;
  296.     data->file = file;
  297.     data->callback = callback;
  298.     data->offset = time;
  299.     data->pending = GetPendingChannels(gLua);
  300.  
  301.     numThreads++;
  302.     HANDLE hThread = CreateThread(NULL, 0, &streamProc, data, 0, NULL);
  303.     if(hThread == NULL)
  304.         numThreads--;
  305.  
  306.     return 0;
  307. }
  308.  
  309. LUA_FUNCTION(poll)
  310. {
  311.     ILuaInterface *gLua = Lua();
  312.  
  313.     SyncList<streamProcData *> *results = GetPendingChannels(gLua);
  314.  
  315.     while(results->getSize() > 0)
  316.     {
  317.         streamProcData *qres = results->remove();
  318.         if(!qres) continue;
  319.  
  320.         gLua->PushReference(qres->callback);
  321.  
  322.         if(qres->handle)
  323.         {
  324.             BASS_ChannelSetAttribute(qres->handle, BASS_ATTRIB_VOL, 1);
  325.  
  326.             ILuaObject* Channel = gLua->GetMetaTable(META_CHANNEL, TYPE_CHANNEL);
  327.             gLua->PushUserData(Channel, (void *)qres->handle);
  328.             Channel->UnReference();
  329.         } else {
  330.             gLua->Push(false);
  331.         }
  332.  
  333.         gLua->Push((float)qres->error);
  334.         gLua->Call(2);
  335.  
  336.         // just incase
  337.         if( qres->file != NULL )
  338.             free(qres->file);
  339.  
  340.         gLua->FreeReference(qres->callback);
  341.         delete qres;
  342.     }
  343.     return 0;
  344. }
  345.  
  346.  
  347. int Start( lua_State* L )
  348. {
  349.     ILuaInterface *gLua = Lua();
  350.    
  351.     HWND gmode = FindWindowA("Valve001", "Garry's Mod");
  352.     if(!gmode)
  353.     {
  354.         gLua->Error("Unable to find Garry's Mod window for BASS library");
  355.         return 0;
  356.     }
  357.  
  358.     BOOL bassInit = BASS_Init(-1, 44100, BASS_DEVICE_3D, gmode, NULL);
  359.     if(!bassInit)
  360.     {
  361.         int error = BASS_ErrorGetCode();
  362.         gLua->Msg("BASS Init failed, error code %d\n", error);
  363.         gLua->Error("BASS Init error");
  364.         return 0;
  365.     }
  366.  
  367.     BASS_SetConfig(BASS_CONFIG_FLOATDSP, true);
  368.     BASS_SetConfig(BASS_CONFIG_NET_PLAYLIST, 1);
  369.  
  370.     ILuaObject* table = gLua->GetNewTable();
  371.         table->SetMember("StreamFile", bass_streamfile);
  372.         table->SetMember("LoadSample", bass_loadsample);
  373.         table->SetMember("StreamFileURL", bass_streamfileurl);
  374.         table->SetMember("SetPosition", bass_setposition);
  375.  
  376.         SyncList<streamProcData *>* pending = new SyncList<streamProcData *>();
  377.         table->SetMemberUserDataLite( "p_PendingChannels", pending );
  378.  
  379.     gLua->SetGlobal("BASS", table);
  380.     table->UnReference();
  381.  
  382.     table = gLua->GetMetaTable(META_CHANNEL, TYPE_CHANNEL);
  383.         table->SetMember("__gc",       channel_gc);
  384.         ILuaObject* __index = gLua->GetNewTable();
  385.             __index->SetMember("Play",  channel_play);
  386.             __index->SetMember("Pause", channel_pause);
  387.             __index->SetMember("Stop",  channel_stop);
  388.             __index->SetMember("GetLength", channel_getlength);
  389.             __index->SetMember("GetPosition",   channel_getposition);
  390.             __index->SetMember("GetTag", channel_gettag);
  391.             __index->SetMember("GetPlaying", channel_getplaying);
  392.             __index->SetMember("GetLevel", channel_getlevel);
  393.             __index->SetMember("SetPosition", channel_setposition);
  394.             __index->SetMember("SetVolume", channel_setvolume);
  395.             __index->SetMember("FFT2048", channel_fft2048);
  396.             __index->SetMember("Set3DPosition", channel_set3dposition);
  397.             __index->SetMember("GetRawTag", channel_getrawtag);
  398.         table->SetMember("__index", __index);
  399.         __index->UnReference();
  400.     table->UnReference();
  401.  
  402.     ILuaObject *hookt = gLua->GetGlobal("hook");
  403.     ILuaObject *addf = hookt->GetMember("Add");
  404.     addf->Push();
  405.     gLua->Push("Think");
  406.     gLua->Push("BASSCallback");
  407.     gLua->Push(poll);
  408.     gLua->Call(3);
  409.  
  410.     return 0;
  411. }
  412.  
  413. int Close( lua_State* L )
  414. {
  415.     BASS_Stop();
  416.  
  417.     while(numThreads > 0)
  418.         Sleep(200);
  419.  
  420.     SyncList<streamProcData *> *pending = GetPendingChannels(Lua());
  421.    
  422.     while(pending->getSize() > 0)
  423.     {
  424.         streamProcData *qres = pending->remove();
  425.         if(!qres) continue;
  426.  
  427.         free(qres->file);
  428.         Lua()->FreeReference(qres->callback);
  429.         delete qres;
  430.     }
  431.  
  432.     delete pending;
  433.     BASS_Free();
  434.     return 0;
  435. }
Advertisement
Add Comment
Please, Sign In to add comment