#include "modules/ImguiModule/ImguiModule.h" #include "modules/ClientModule/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; }