Compare commits
4 Commits
b8fba92ea7
...
53695cbc60
| Author | SHA1 | Date | |
|---|---|---|---|
| 53695cbc60 | |||
| 101fcf4781 | |||
| 421bf37b75 | |||
| 2182abc714 |
@@ -249,6 +249,40 @@
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ChatServerVoice = pkgs.stdenvNoCC.mkDerivation {
|
||||||
|
|
||||||
|
name = "ChatServerVoice";
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [
|
||||||
|
clang
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
gamenetworkingsockets
|
||||||
|
];
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
clang++ \
|
||||||
|
modules/examples/ChatServerVoice/src/*.cpp \
|
||||||
|
modules/ServerModule/src/*.cpp \
|
||||||
|
-fpic -shared \
|
||||||
|
-I ${pkgs.gamenetworkingsockets}/include/GameNetworkingSockets \
|
||||||
|
-I src -I include -I . \
|
||||||
|
-lGameNetworkingSockets \
|
||||||
|
-DCHATSERVERVOICE_DYNAMIC \
|
||||||
|
-Wall \
|
||||||
|
-o $name
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp $name $out/bin
|
||||||
|
'';
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
ChatClient = pkgs.stdenvNoCC.mkDerivation {
|
ChatClient = pkgs.stdenvNoCC.mkDerivation {
|
||||||
|
|
||||||
name = "ChatClient";
|
name = "ChatClient";
|
||||||
@@ -295,4 +329,51 @@
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ChatClientVoice = pkgs.stdenvNoCC.mkDerivation {
|
||||||
|
|
||||||
|
name = "ChatClientVoice";
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
imgui = inputs.imgui;
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [
|
||||||
|
clang
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
gamenetworkingsockets
|
||||||
|
sdl3
|
||||||
|
glew
|
||||||
|
];
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
clang++ \
|
||||||
|
modules/examples/ChatClientVoice/src/*.cpp \
|
||||||
|
modules/ClientModule/src/*.cpp \
|
||||||
|
-I ${pkgs.gamenetworkingsockets}/include/GameNetworkingSockets \
|
||||||
|
-lGameNetworkingSockets \
|
||||||
|
-DCHATCLIENTVOICE_DYNAMIC \
|
||||||
|
modules/WindowModule/src/*.cpp \
|
||||||
|
modules/ImguiModule/src/*.cpp \
|
||||||
|
$imgui/backends/imgui_impl_sdl3.cpp \
|
||||||
|
$imgui/backends/imgui_impl_opengl3.cpp \
|
||||||
|
$imgui/misc/cpp/*.cpp \
|
||||||
|
$imgui/*.cpp \
|
||||||
|
-DRENDERER=1 \
|
||||||
|
-DWINDOW=2 \
|
||||||
|
-fpic -shared \
|
||||||
|
-I src -I include -I $imgui -I . \
|
||||||
|
-lGL -lSDL3 -lGLEW \
|
||||||
|
-Wall \
|
||||||
|
-o $name
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp $name $out/bin
|
||||||
|
'';
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,20 @@
|
|||||||
#ifndef AUDIO_H
|
#ifndef AUDIO_H
|
||||||
#define AUDIO_H
|
#define AUDIO_H
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
#include <SDL3/SDL_audio.h>
|
#include <SDL3/SDL_audio.h>
|
||||||
|
|
||||||
namespace Archimedes {
|
namespace Archimedes {
|
||||||
|
|
||||||
class Audio {
|
class Audio {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Audio() {}
|
||||||
|
|
||||||
|
~Audio() {}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
250
modules/examples/ChatClientVoice/src/ChatClientVoice.cpp
Normal file
250
modules/examples/ChatClientVoice/src/ChatClientVoice.cpp
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
|
||||||
|
#include "modules/ImguiModule/src/ImguiModule.h"
|
||||||
|
|
||||||
|
#include "modules/ClientModule/src/ClientModule.h"
|
||||||
|
|
||||||
|
#include "ChatClientVoice.h"
|
||||||
|
|
||||||
|
|
||||||
|
ChatClientVoice::ChatClientVoice(Archimedes::App* a, void* h) : Module(a, h) {
|
||||||
|
|
||||||
|
name = "ChatClientVoice";
|
||||||
|
|
||||||
|
ClientModule* cm = new ClientModule(a, h);
|
||||||
|
deps[*cm] = cm;
|
||||||
|
cm->shouldHandleEvents(ClientModule::CMEventEnum::ConnectionStatusChanged | ClientModule::CMEventEnum::DataSent);
|
||||||
|
|
||||||
|
ImguiModule* im = new ImguiModule(a, h);
|
||||||
|
|
||||||
|
deps[*im] = im;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatClientVoice::~ChatClientVoice() {
|
||||||
|
if(app) {
|
||||||
|
|
||||||
|
ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; }
|
||||||
|
|
||||||
|
im->releaseContext(ImGui::GetCurrentContext());
|
||||||
|
|
||||||
|
//if(buf)
|
||||||
|
// delete [] buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatClientVoice::onLoad() {
|
||||||
|
|
||||||
|
ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; }
|
||||||
|
|
||||||
|
if(!im) {
|
||||||
|
std::cout << "No ImguiModule for ChatClientVoice!\n";
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SetCurrentContext(im->aquireContext());
|
||||||
|
|
||||||
|
ClientModule* cm; { cm = (ClientModule*) moduleInstances[ClientModule()]; }
|
||||||
|
|
||||||
|
if(!cm) {
|
||||||
|
std::cout << "No ClientModule for ChatClientVoice!\n";
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!SDL_Init(SDL_INIT_AUDIO)) {
|
||||||
|
std::cout << "Audio init failed!\n";
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
mic = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_RECORDING, NULL, NULL, NULL);
|
||||||
|
SDL_GetAudioStreamFormat(mic, &spec, NULL);
|
||||||
|
speaker = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, NULL, NULL);
|
||||||
|
|
||||||
|
//buf = new unsigned char[len];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatClientVoice::run() {
|
||||||
|
|
||||||
|
static ClientModule* cm; { cm = (ClientModule*) moduleInstances[ClientModule()]; }
|
||||||
|
|
||||||
|
static unsigned char buf[10 * 1024];
|
||||||
|
|
||||||
|
if(!cm) {
|
||||||
|
std::cout << "No ClientModule for ChatClientVoice!\n";
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(open) {
|
||||||
|
static std::string s, addr = "127.0.0.1:9932";
|
||||||
|
|
||||||
|
ImGui::Begin("ChatClientVoice Module", &open);
|
||||||
|
|
||||||
|
ImGui::InputText("Server Address: ", &addr);
|
||||||
|
|
||||||
|
if(cm->isRunning() && cm->isConnected()) {
|
||||||
|
|
||||||
|
if(ImGui::Button("Disconnect") && cm->isRunning()) {
|
||||||
|
cm->stopClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if(ImGui::Button("Connect") && !cm->isRunning()) {
|
||||||
|
static SteamNetworkingIPAddr serverAddr;
|
||||||
|
serverAddr.ParseString(addr.c_str());
|
||||||
|
cm->startClient(serverAddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ImGui::Text("%s", messages.c_str());
|
||||||
|
|
||||||
|
ImGui::InputText("Message: ", &s);
|
||||||
|
|
||||||
|
if(cm->isConnected()) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
if(ImGui::Button("send")) {
|
||||||
|
s.insert(s.begin(), 'o');
|
||||||
|
s.insert(s.begin(), ' ');
|
||||||
|
s.insert(s.begin(), '0');
|
||||||
|
s.insert(s.begin(), 'a');
|
||||||
|
cm->sendReliable(s.c_str(), (uint32) s.length());
|
||||||
|
s.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static float micVol = 1.0f;
|
||||||
|
static float speakerVol = 1.0f;
|
||||||
|
|
||||||
|
static bool micTest = false;
|
||||||
|
|
||||||
|
ImGui::SliderFloat("Mic Volume", &micVol, 0.0f, 1.0f);
|
||||||
|
ImGui::SliderFloat("Speaker Volume", &speakerVol, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
ImGui::Checkbox("Mic test", &micTest);
|
||||||
|
|
||||||
|
if(!SDL_AudioStreamDevicePaused(mic)) {
|
||||||
|
SDL_SetAudioStreamGain(mic, micVol);
|
||||||
|
} else if(micTest) {
|
||||||
|
SDL_ClearAudioStream(mic);
|
||||||
|
SDL_ResumeAudioStreamDevice(mic);
|
||||||
|
SDL_SetAudioStreamGain(mic, micVol);
|
||||||
|
} else if(!cm->isConnected()) {
|
||||||
|
SDL_PauseAudioStreamDevice(mic);
|
||||||
|
SDL_ClearAudioStream(mic);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!SDL_AudioStreamDevicePaused(speaker)) {
|
||||||
|
SDL_SetAudioStreamGain(speaker, speakerVol);
|
||||||
|
} else if(micTest) {
|
||||||
|
SDL_ClearAudioStream(speaker);
|
||||||
|
SDL_ResumeAudioStreamDevice(speaker);
|
||||||
|
SDL_SetAudioStreamGain(speaker, speakerVol);
|
||||||
|
} else if(!cm->isConnected()) {
|
||||||
|
SDL_PauseAudioStreamDevice(speaker);
|
||||||
|
SDL_ClearAudioStream(speaker);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int avail = 0;
|
||||||
|
|
||||||
|
if(micTest) {
|
||||||
|
|
||||||
|
avail = SDL_min(len, SDL_GetAudioStreamAvailable(mic));
|
||||||
|
avail = SDL_GetAudioStreamData(mic, buf, avail);
|
||||||
|
|
||||||
|
SDL_PutAudioStreamData(speaker, buf, avail);
|
||||||
|
|
||||||
|
} else if(cm->isConnected()){
|
||||||
|
// if not testing, send to server.
|
||||||
|
|
||||||
|
avail = SDL_min(len, SDL_GetAudioStreamAvailable(mic));
|
||||||
|
if(avail > 10) {
|
||||||
|
avail = SDL_GetAudioStreamData(mic, buf, avail);
|
||||||
|
cm->sendReliable(buf, avail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
} else {
|
||||||
|
app->emitEvent(new Archimedes::DoUnloadModuleEvent(*cm));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChatClientVoice::onEvent(const Archimedes::Event& event) {
|
||||||
|
|
||||||
|
unsigned int type = app->getEventType(event);
|
||||||
|
|
||||||
|
/*if(type == app->getEventType("DataSentEvent")) {
|
||||||
|
//we did this?
|
||||||
|
return true;
|
||||||
|
} else */
|
||||||
|
|
||||||
|
if(type == app->getEventType(Archimedes::DataRecievedEvent())) {
|
||||||
|
|
||||||
|
Archimedes::DataRecievedEvent& e = (Archimedes::DataRecievedEvent&) event;
|
||||||
|
|
||||||
|
static std::string s;
|
||||||
|
|
||||||
|
if(((char*)e.msg->m_pData)[0] == 'a' && ((char*)e.msg->m_pData)[1] == '0' && ((char*)e.msg->m_pData)[2] == ' ' && ((char*)e.msg->m_pData)[3] == 'o') {
|
||||||
|
s = std::string((const char*)e.msg->m_pData + 4, e.msg->m_cbSize - 4);
|
||||||
|
|
||||||
|
messages += "\n\n" + s;
|
||||||
|
} else {
|
||||||
|
s = "audio data";
|
||||||
|
|
||||||
|
SDL_PutAudioStreamData(speaker, e.msg->m_pData, e.msg->m_cbSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "Client Recieved: " << s << std::endl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else if(type == app->getEventType("ConnectionStatusChangedEvent")) {
|
||||||
|
|
||||||
|
Archimedes::ConnectionStatusChangedEvent& e = (Archimedes::ConnectionStatusChangedEvent&) event;
|
||||||
|
|
||||||
|
switch(e.info->m_info.m_eState) {
|
||||||
|
|
||||||
|
case k_ESteamNetworkingConnectionState_None:
|
||||||
|
// NOTE: We will get callbacks here when we destroy connections. You can ignore these.
|
||||||
|
break;
|
||||||
|
|
||||||
|
case k_ESteamNetworkingConnectionState_ClosedByPeer:
|
||||||
|
case k_ESteamNetworkingConnectionState_ProblemDetectedLocally:
|
||||||
|
{
|
||||||
|
|
||||||
|
SDL_PauseAudioStreamDevice(mic);
|
||||||
|
SDL_PauseAudioStreamDevice(speaker);
|
||||||
|
SDL_ClearAudioStream(mic);
|
||||||
|
SDL_ClearAudioStream(speaker);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case k_ESteamNetworkingConnectionState_Connecting:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case k_ESteamNetworkingConnectionState_Connected:
|
||||||
|
//OnConnect
|
||||||
|
SDL_ClearAudioStream(mic);
|
||||||
|
SDL_ClearAudioStream(speaker);
|
||||||
|
SDL_ResumeAudioStreamDevice(mic);
|
||||||
|
SDL_ResumeAudioStreamDevice(speaker);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Silences -Wswitch
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
36
modules/examples/ChatClientVoice/src/ChatClientVoice.h
Normal file
36
modules/examples/ChatClientVoice/src/ChatClientVoice.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include "Archimedes.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#include <SDL3/SDL_audio.h>
|
||||||
|
|
||||||
|
class ChatClientVoice : public Archimedes::Module {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ChatClientVoice(Archimedes::App* a, void* h);
|
||||||
|
|
||||||
|
ChatClientVoice() { name = "ChatClientVoice"; }
|
||||||
|
|
||||||
|
~ChatClientVoice();
|
||||||
|
|
||||||
|
void onLoad() override;
|
||||||
|
|
||||||
|
void run() override;
|
||||||
|
|
||||||
|
bool onEvent(const Archimedes::Event&) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string messages = "";
|
||||||
|
bool open = true;
|
||||||
|
|
||||||
|
SDL_AudioSpec spec;
|
||||||
|
SDL_AudioStream *mic, *speaker;
|
||||||
|
|
||||||
|
const int len = 10 * 1024;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CHATCLIENTVOICE_DYNAMIC
|
||||||
|
#define MODULE_TYPE ChatClientVoice
|
||||||
|
#include "endModule.h"
|
||||||
|
#endif
|
||||||
68
modules/examples/ChatServerVoice/src/ChatServerVoice.cpp
Normal file
68
modules/examples/ChatServerVoice/src/ChatServerVoice.cpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#include "ChatServerVoice.h"
|
||||||
|
|
||||||
|
void ChatServerVoice::onLoad() {
|
||||||
|
ServerModule* sm = (ServerModule*) moduleInstances[ServerModule()];
|
||||||
|
|
||||||
|
sm->startServer(9932);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void ChatServerVoice::run() {}
|
||||||
|
|
||||||
|
bool ChatServerVoice::onEvent(const Archimedes::Event& event) {
|
||||||
|
|
||||||
|
unsigned int type = app->getEventType(event);
|
||||||
|
|
||||||
|
|
||||||
|
/*if(type == app->getEventType("DataSentEvent")) {
|
||||||
|
//we did this?
|
||||||
|
return true;
|
||||||
|
} else */
|
||||||
|
|
||||||
|
if(type == app->getEventType(Archimedes::DataRecievedEvent())) {
|
||||||
|
|
||||||
|
static ServerModule* sm; { sm = (ServerModule*) moduleInstances[ServerModule()]; }
|
||||||
|
|
||||||
|
Archimedes::DataRecievedEvent& e = (Archimedes::DataRecievedEvent&) event;
|
||||||
|
static std::string s;
|
||||||
|
|
||||||
|
if(((char*)e.msg->m_pData)[0] == 'a' && ((char*)e.msg->m_pData)[1] == '0' && ((char*)e.msg->m_pData)[2] == ' ' && ((char*)e.msg->m_pData)[3] == 'o') {
|
||||||
|
s = std::string((const char*)e.msg->m_pData + 4, e.msg->m_cbSize - 4);
|
||||||
|
|
||||||
|
if(s == "/quit") {
|
||||||
|
sm->disconnectClient(e.msg->m_conn);
|
||||||
|
} else if(s == "/shutdown") {
|
||||||
|
sm->stopServer();
|
||||||
|
app->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto& it : sm->getClients()) {
|
||||||
|
if(it.first != e.msg->m_conn)
|
||||||
|
sm->sendReliable(it.first, e.msg->m_pData, e.msg->m_cbSize);
|
||||||
|
else
|
||||||
|
sm->sendReliable(e.msg->m_conn, "a0 o\nMessage sent\n", strlen("a0 o\nMessage sent\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
s = "audio data";
|
||||||
|
|
||||||
|
for(auto& it : sm->getClients()) {
|
||||||
|
if(it.first != e.msg->m_conn)
|
||||||
|
sm->sendReliable(it.first, e.msg->m_pData, e.msg->m_cbSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "Server Recieved: " << s << std::endl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} /*else if(type == app->getEventType("ConnectionStatusChangedEvent")) {
|
||||||
|
|
||||||
|
//Archimedes::ConnectionStatusChangedEvent& e = (Archimedes::ConnectionStatusChangedEvent&) event;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
34
modules/examples/ChatServerVoice/src/ChatServerVoice.h
Normal file
34
modules/examples/ChatServerVoice/src/ChatServerVoice.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#include "Archimedes.h"
|
||||||
|
|
||||||
|
#include "modules/ServerModule/src/ServerModule.h"
|
||||||
|
|
||||||
|
class ChatServerVoice : public Archimedes::Module {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ChatServerVoice(Archimedes::App* a, void* h) : Module(a, h) {
|
||||||
|
|
||||||
|
name = "ChatServerVoice";
|
||||||
|
|
||||||
|
ServerModule* sm = new ServerModule(a, h);
|
||||||
|
deps[*sm] = sm;
|
||||||
|
sm->shouldHandleEvents(ServerModule::SMEventEnum::ConnectionStatusChanged | ServerModule::SMEventEnum::DataSent);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatServerVoice() { name = "ChatServerVoice"; }
|
||||||
|
|
||||||
|
~ChatServerVoice() {
|
||||||
|
if(app) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onLoad();
|
||||||
|
|
||||||
|
//void run();
|
||||||
|
|
||||||
|
bool onEvent(const Archimedes::Event&);
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CHATSERVERVOICE_DYNAMIC
|
||||||
|
#define MODULE_TYPE ChatServerVoice
|
||||||
|
#include "endModule.h"
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user