Skip to content

Commit 7b7056a

Browse files
committed
bass: extent it even more
1 parent f39e1ed commit 7b7056a

File tree

6 files changed

+166
-2
lines changed

6 files changed

+166
-2
lines changed

source/lua.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,12 @@ extern void Push_CBaseClient(GarrysMod::Lua::ILuaInterface* LUA, CBaseClient* tb
10221022
extern CBaseClient* Get_CBaseClient(GarrysMod::Lua::ILuaInterface* LUA, int iStackPos, bool bError);
10231023
#endif
10241024

1025+
#if MODULE_EXISTS_VOICECHAT
1026+
struct VoiceData;
1027+
extern LuaUserData* Push_VoiceData(GarrysMod::Lua::ILuaInterface* LUA, VoiceData* tbl);
1028+
extern VoiceData* Get_VoiceData(GarrysMod::Lua::ILuaInterface* LUA, int iStackPos, bool bError);
1029+
#endif
1030+
10251031
// NOTE: The angle itself is pushed, not a copy, any changes from lua will affect it!
10261032
extern void Push_QAngle(GarrysMod::Lua::ILuaInterface* LUA, QAngle* var);
10271033

source/modules/bass.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,63 @@ LUA_FUNCTION_STATIC(IGModAudioChannel_CreateEncoder)
547547
return 2;
548548
}
549549

550+
LUA_FUNCTION_STATIC(IGModAudioChannelEncoder_SetPaused)
551+
{
552+
IGModAudioChannelEncoder* encoder = Get_IGModAudioChannelEncoder(LUA, 1, true);
553+
554+
encoder->SetPaused(LUA->GetBool(2));
555+
return 0;
556+
}
557+
558+
LUA_FUNCTION_STATIC(IGModAudioChannelEncoder_GetState)
559+
{
560+
IGModAudioChannelEncoder* encoder = Get_IGModAudioChannelEncoder(LUA, 1, true);
561+
562+
LUA->PushNumber(encoder->GetState());
563+
return 1;
564+
}
565+
566+
LUA_FUNCTION_STATIC(IGModAudioChannelEncoder_SetChannel)
567+
{
568+
IGModAudioChannelEncoder* encoder = Get_IGModAudioChannelEncoder(LUA, 1, true);
569+
IGModAudioChannel* channel = Get_IGModAudioChannel(LUA, 2, true);
570+
571+
const char* pErrorCode = nullptr;
572+
encoder->SetChannel(channel, &pErrorCode);
573+
LUA->PushBool(pErrorCode == nullptr);
574+
if (pErrorCode) {
575+
LUA->PushString(pErrorCode);
576+
} else {
577+
LUA->PushNil();
578+
}
579+
return 2;
580+
}
581+
582+
LUA_FUNCTION_STATIC(IGModAudioChannelEncoder_InsertVoiceData)
583+
{
584+
IGModAudioChannelEncoder* encoder = Get_IGModAudioChannelEncoder(LUA, 1, true);
585+
586+
#if MODULE_EXISTS_VOICECHAT
587+
VoiceData* pVoiceData = Get_VoiceData(LUA, 2, true);
588+
extern char* VoiceData_GetDecompressedData(VoiceData* pData, int* pLength); // exposed for us :3
589+
590+
int nLength = -1;
591+
char* pRawData = VoiceData_GetDecompressedData(pVoiceData, &nLength);
592+
if (!pRawData)
593+
{
594+
LUA->PushBool(false);
595+
return 1;
596+
}
597+
598+
encoder->WriteData(pRawData, nLength);
599+
#else
600+
MISSING_MODULE_ERROR(LUA, voicechat);
601+
#endif
602+
603+
LUA->PushBool(true);
604+
return 1;
605+
}
606+
550607
LUA_FUNCTION_STATIC(bass_PlayFile)
551608
{
552609
const char* filePath = LUA->CheckString(1);
@@ -614,6 +671,23 @@ LUA_FUNCTION_STATIC(bass_GetVersion)
614671
return 1;
615672
}
616673

674+
LUA_FUNCTION_STATIC(bass_CreateDummyChannel)
675+
{
676+
int nSampleRate = LUA->CheckNumber(1);
677+
int nChannels = LUA->CheckNumber(2);
678+
unsigned long nFlags = (unsigned long)LUA->CheckNumber(3);
679+
680+
const char* pErrorCode = nullptr;
681+
IGModAudioChannel* pChannel = gGModAudio->CreateDummyChannel(nSampleRate, nChannels, nFlags, &pErrorCode);
682+
Push_IGModAudioChannel(LUA, pChannel);
683+
if (pErrorCode) {
684+
LUA->PushString(pErrorCode);
685+
} else {
686+
LUA->PushNil();
687+
}
688+
return 2;
689+
}
690+
617691
LUA_FUNCTION_STATIC(bass_LoadPlugin)
618692
{
619693
const char* pError = NULL;
@@ -666,6 +740,9 @@ void CBassModule::LuaInit(GarrysMod::Lua::ILuaInterface* pLua, bool bServerInit)
666740
Util::AddFunc(pLua, IGModAudioChannelEncoder__index, "__index");
667741
Util::AddFunc(pLua, IGModAudioChannelEncoder__newindex, "__newindex");
668742
Util::AddFunc(pLua, IGModAudioChannelEncoder_MakeServer, "MakeServer");
743+
Util::AddFunc(pLua, IGModAudioChannelEncoder_SetPaused, "SetPaused");
744+
Util::AddFunc(pLua, IGModAudioChannelEncoder_GetState, "GetState");
745+
Util::AddFunc(pLua, IGModAudioChannelEncoder_SetChannel, "SetChannel");
669746
pLua->Pop(1);
670747

671748
Lua::GetLuaData(pLua)->RegisterMetaTable(Lua::IGModAudioChannel, pLua->CreateMetaTable("IGModAudioChannel"));
@@ -726,6 +803,7 @@ void CBassModule::LuaInit(GarrysMod::Lua::ILuaInterface* pLua, bool bServerInit)
726803
Util::AddFunc(pLua, bass_PlayURL, "PlayURL");
727804
Util::AddFunc(pLua, bass_Update, "Update");
728805
Util::AddFunc(pLua, bass_GetVersion, "GetVersion");
806+
Util::AddFunc(pLua, bass_CreateDummyChannel, "CreateDummyChannel");
729807
// Util::AddFunc(pLua, bass_LoadPlugin, "LoadPlugin");
730808
Util::FinishTable(pLua, "bass");
731809
}

source/modules/voicechat.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,12 @@ struct VoiceData
302302
char* pDecompressedData = nullptr;
303303
};
304304

305+
// For other modules to utilize since we don't expose the struct. Looking at you bass
306+
char* VoiceData_GetDecompressedData(VoiceData* pData, int* pLength)
307+
{
308+
return pData->GetDecompressedData(pLength);
309+
}
310+
305311
Push_LuaClass(VoiceData)
306312
Get_LuaClass(VoiceData, "VoiceData")
307313

source/sourcesdk/IGmod_Audio.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,36 @@ enum GModEncoderStatus {
2424
};
2525

2626
// HolyLib specific
27-
// NOTE: Always call GetLastError after any function call to check for errors!
27+
// NOTE: Always call GetLastError after any function call that throws one to check for errors!
28+
class IGModAudioChannel;
2829
class IGModAudioChannelEncoder
2930
{
3031
public:
3132
virtual ~IGModAudioChannelEncoder() {};
3233

3334
// ProcessNow uses BASS_ChannelGetData to pull data, so this function only works on decode channels!
35+
// Will throw an error to check with GetLastError
3436
virtual void ProcessNow(bool bUseAnotherThread) = 0;
37+
3538
virtual void Stop(bool bProcessQueue) = 0;
39+
3640
// Returns true if there was an error, pErrorOut will either be filled or NULL
3741
// If it returns true, it will also invalidate/free itself so the pointer becomes invalid!
42+
// NOTE: This is only for fatal errors like on init, most other functions have a pErrorOut argument for light errors that can be ignored
3843
virtual bool GetLastError(const char** pErrorOut) = 0;
44+
3945
// Wasn't exposed since CreateEncoder already calls it so it has no real use
4046
// virtual void InitEncoder(unsigned long nEncoderFlags) = 0;
4147

4248
virtual bool MakeServer( const char* port, unsigned long buffer, unsigned long burst, unsigned long flags, const char** pErrorOut ) = 0;
49+
50+
virtual void SetPaused( bool bPaused ) = 0;
51+
virtual int GetState() = 0;
52+
53+
// virtual IGModAudioChannel* GetChannel() = 0;
54+
virtual void SetChannel( IGModAudioChannel* pChannel, const char** pErrorOut ) = 0;
55+
56+
virtual void WriteData(const void* pData, unsigned long nLength) = 0;
4357
};
4458

4559
class IGModAudioChannelEncoder;
@@ -141,6 +155,7 @@ abstract_class IGMod_Audio
141155
virtual unsigned long GetVersion() = 0; // Returns bass version
142156
virtual bool LoadPlugin(const char* pluginName, const char** pErrorOut) = 0;
143157
virtual void FinishAllAsync(void* nSignalData) = 0; // Called on Lua shutdown to finish all callbacks/async tasks for that interface
158+
virtual IGModAudioChannel* CreateDummyChannel(int nSampleRate, int nChannels, unsigned long nFlags, const char** pErrorOut) = 0;
144159
};
145160

146161
#undef CALLBACK // Solves another error with minwindef.h

source/sourcesdk/cgmod_audio.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ static BASS_Encode_StopEx* func_BASS_Encode_StopEx;
257257
static BASS_Encode_SetNotify* func_BASS_Encode_SetNotify;
258258
static BASS_Encode_IsActive* func_BASS_Encode_IsActive;
259259
static BASS_Encode_ServerInit* func_BASS_Encode_ServerInit;
260+
static BASS_Encode_SetPaused* func_BASS_Encode_SetPaused;
261+
static BASS_Encode_GetChannel* func_BASS_Encode_GetChannel;
262+
static BASS_Encode_SetChannel* func_BASS_Encode_SetChannel;
263+
static BASS_Encode_Write* func_BASS_Encode_Write;
260264

261265
static BASS_Encode_MP3_Start* func_BASS_Encode_MP3_Start;
262266
static BASS_Encode_OGG_Start* func_BASS_Encode_OGG_Start;
@@ -336,6 +340,10 @@ bool CGMod_Audio::Init(CreateInterfaceFn interfaceFactory)
336340
GetBassEncFunc(BASS_Encode_SetNotify, pBassEnc);
337341
GetBassEncFunc(BASS_Encode_IsActive, pBassEnc);
338342
GetBassEncFunc(BASS_Encode_ServerInit, pBassEnc);
343+
GetBassEncFunc(BASS_Encode_SetPaused, pBassEnc);
344+
GetBassEncFunc(BASS_Encode_GetChannel, pBassEnc);
345+
GetBassEncFunc(BASS_Encode_SetChannel, pBassEnc);
346+
GetBassEncFunc(BASS_Encode_Write, pBassEnc);
339347
g_bUsesBassEnc = true;
340348
}
341349

@@ -635,6 +643,18 @@ void CGMod_Audio::FinishAllAsync(void* nSignalData)
635643
Msg("FinishAllAsync done\n");
636644
}
637645

646+
IGModAudioChannel* CGMod_Audio::CreateDummyChannel(int nSampleRate, int nChannels, unsigned long nFlags, const char** pErrorOut)
647+
{
648+
HSTREAM pStream = BASS_StreamCreate(nSampleRate, nChannels, nFlags, STREAMPROC_DUMMY, NULL);
649+
if (!pStream)
650+
{
651+
*pErrorOut = BassErrorToString(BASS_ErrorGetCode());
652+
return NULL;
653+
}
654+
655+
return new CGModAudioChannel(pStream, true, "DUMMY");
656+
}
657+
638658
// We gotta load some DLLs first as bass won't load shit itself when using BASS_PluginLoad >:(
639659
bool CGMod_Audio::LoadDLL(const char* pDLLName, void** pDLLHandle)
640660
{
@@ -844,7 +864,7 @@ void CGModAudioChannel::Get3DCone(int* innerAngle, int* outerAngle, float* outer
844864

845865
int CGModAudioChannel::GetState()
846866
{
847-
return BASS_ChannelIsActive(m_pHandle);
867+
return BASS_ChannelIsActive(m_pHandle)-1; // Why -1? Because their all shifted by +1 so they do not match gmod's expected enums
848868
}
849869

850870
void CGModAudioChannel::SetLooping(bool looping)
@@ -1246,4 +1266,32 @@ bool CGModAudioChannelEncoder::MakeServer( const char* port, unsigned long buffe
12461266
}
12471267

12481268
return true;
1269+
}
1270+
1271+
void CGModAudioChannelEncoder::SetPaused(bool bPaused)
1272+
{
1273+
func_BASS_Encode_SetPaused( m_pEncoder, bPaused );
1274+
}
1275+
1276+
int CGModAudioChannelEncoder::GetState()
1277+
{
1278+
return (int)func_BASS_Encode_IsActive( m_pEncoder );
1279+
}
1280+
1281+
/*IGModAudioChannel* CGModAudioChannelEncoder::GetChannel()
1282+
{
1283+
return func_BASS_Encode_GetChannel( m_pEncoder );
1284+
}*/
1285+
1286+
void CGModAudioChannelEncoder::SetChannel(IGModAudioChannel* pChannel, const char** pErrorOut)
1287+
{
1288+
*pErrorOut = NULL;
1289+
1290+
if (func_BASS_Encode_SetChannel( m_pEncoder, ((CGModAudioChannel*)pChannel)->m_pHandle ) == 0)
1291+
*pErrorOut = BassErrorToString(BASS_ErrorGetCode());
1292+
}
1293+
1294+
void CGModAudioChannelEncoder::WriteData(const void* pData, unsigned long nLength)
1295+
{
1296+
func_BASS_Encode_Write( m_pEncoder, pData, nLength );
12491297
}

source/sourcesdk/cgmod_audio.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ class CGModAudioChannelEncoder : public IGModAudioChannelEncoder
4949
virtual bool GetLastError(const char** pErrorOut);
5050
virtual bool MakeServer( const char* port, unsigned long buffer, unsigned long burst, unsigned long flags, const char** pErrorOut );
5151

52+
virtual void SetPaused( bool bPaused );
53+
virtual int GetState();
54+
55+
// virtual IGModAudioChannel* GetChannel();
56+
virtual void SetChannel( IGModAudioChannel* pChannel, const char** pErrorOut );
57+
58+
virtual void WriteData(const void* pData, unsigned long nLength);
59+
5260
public: // Non virtual
5361
CGModAudioChannelEncoder(DWORD pChannel, const char* pFileName, IGModEncoderCallback* pCallback );
5462
void InitEncoder(unsigned long nEncoderFlags);
@@ -126,6 +134,8 @@ class CGModAudioChannel : public IGModAudioChannel
126134

127135
bool IsDecode();
128136
private:
137+
friend class CGModAudioChannelEncoder;
138+
129139
DWORD m_pHandle;
130140
bool m_bIsFile;
131141
std::string m_strFileName = "NULL"; // GMOD doesn't have this - HolyLib specific
@@ -151,6 +161,7 @@ class CGMod_Audio : public IGMod_Audio
151161
virtual bool LoadPlugin(const char* pluginName, const char** pErrorOut);
152162

153163
virtual void FinishAllAsync(void* nSignalData);
164+
virtual IGModAudioChannel* CreateDummyChannel(int nSampleRate, int nChannels, unsigned long nFlags, const char** pErrorOut);
154165

155166
public: // Non virtual holylib functions
156167
void AddEncoder(CGModAudioChannelEncoder* pEncoder) {

0 commit comments

Comments
 (0)