diff --git a/CMakeLists.txt b/CMakeLists.txt index b14f1694..9944d758 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR) -project(pamworkspace VERSION 1.3.0.0) +project(pamworkspace VERSION 1.3.2) SET(CMAKE_CXX_STANDARD 14) diff --git a/documents/pam2.ini b/documents/pam2.ini index d47f8be6..1c0b039e 100644 --- a/documents/pam2.ini +++ b/documents/pam2.ini @@ -116,11 +116,11 @@ _Options=0 [Server] DestinationIp=239.34.13.86 Multicast=239.56.138.33 -PacketTime=333 +PacketTime=1000 RTP_Port=5004 RTSP_Address=192.168.1.123 RTSP_Interface=eth0 -Stream=Multicast +Stream=AlwaysOn [Session Info] Graph=kBit/s _Options=0 diff --git a/pam2/CMakeLists.txt b/pam2/CMakeLists.txt index f573bf0a..2fd6ad11 100644 --- a/pam2/CMakeLists.txt +++ b/pam2/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR) -project(pam2 LANGUAGES CXX VERSION 1.3.1) +project(pam2 LANGUAGES CXX VERSION 1.3.2) execute_process(COMMAND ${CMAKE_COMMAND} -DNAMESPACE=${PROJECT_NAME} -DMAJOR=${PROJECT_VERSION_MAJOR} -DMINOR=${PROJECT_VERSION_MINOR} -DPATCH=${PROJECT_VERSION_PATCH} -P ${CMAKE_SOURCE_DIR}/version.cmake) diff --git a/pam2/dlgmask.cpp b/pam2/dlgmask.cpp index 912b3176..b3da45f8 100644 --- a/pam2/dlgmask.cpp +++ b/pam2/dlgmask.cpp @@ -66,7 +66,6 @@ void dlgMask::OnActivate(wxActivateEvent& event) void dlgMask::OnlstSubnetSelected(wxCommandEvent& event) { m_sSelected = event.GetString(); - pmlLog(pml::LOG_INFO) << "Selected a value " << m_sSelected; if(HasCapture()) { ReleaseMouse(); @@ -82,7 +81,6 @@ void dlgMask::OnLeftDown(wxMouseEvent& event) { ReleaseMouse(); } - pmlLog(pml::LOG_INFO) << "Clicked outside"; EndModal(wxID_CANCEL); } else @@ -95,7 +93,6 @@ void dlgMask::OnLeftDown(wxMouseEvent& event) void dlgMask::OnCaptureLost(wxMouseCaptureLostEvent& event) { - pmlLog(pml::LOG_INFO) << "Capture lost"; wxPostEvent(m_plstSubnet, event); // EndModal(wxID_CANCEL); // CaptureMouse(); diff --git a/pam2/nmos.cpp b/pam2/nmos.cpp index 42b178e8..178350d5 100644 --- a/pam2/nmos.cpp +++ b/pam2/nmos.cpp @@ -417,7 +417,7 @@ void NmosManager::ActivateSender(const std::string& sId) { Settings::Get().Write("Output", "Destination", "AoIP"); } - Settings::Get().Write("Server", "Stream", "Multicast"); + Settings::Get().Write("Server", "Stream", "AlwaysOn"); IOManager::Get().RestartStream(); } diff --git a/pam2/pnlAoipManual.cpp b/pam2/pnlAoipManual.cpp index 6025e178..63ca68c8 100644 --- a/pam2/pnlAoipManual.cpp +++ b/pam2/pnlAoipManual.cpp @@ -18,7 +18,7 @@ const long pnlAoipManual::ID_M_PLBL2 = wxNewId(); const long pnlAoipManual::ID_M_PBTN6 = wxNewId(); const long pnlAoipManual::ID_M_PBTN1 = wxNewId(); const long pnlAoipManual::ID_M_PLBL4 = wxNewId(); -const long pnlAoipManual::ID_M_PLST5 = wxNewId(); +const long pnlAoipManual::ID_M_PBTN2 = wxNewId(); const long pnlAoipManual::ID_M_PKBD2 = wxNewId(); const long pnlAoipManual::ID_M_PBTN3 = wxNewId(); const long pnlAoipManual::ID_M_PLBL11 = wxNewId(); @@ -58,6 +58,7 @@ pnlAoipManual::pnlAoipManual(wxWindow* parent,wxWindowID id,const wxPoint& pos,c m_pbtnSampleRate = new wmButton(this, ID_M_PBTN6, _("48000"), wxPoint(110,60), wxSize(92,40), wmButton::STYLE_NORMAL, wxDefaultValidator, _T("ID_M_PBTN6")); m_pbtnSampleRate->SetForegroundColour(wxColour(0,0,0)); m_pbtnSampleRate->SetBackgroundColour(wxColour(255,255,255)); + m_pbtnSampleRate->SetColourDisabled(wxColour(wxT("#B0B0B0"))); m_pbtnBits = new wmButton(this, ID_M_PBTN1, _("Bits"), wxPoint(260,60), wxSize(200,40), wmButton::STYLE_SELECT, wxDefaultValidator, _T("ID_M_PBTN1")); m_pbtnBits->SetBackgroundColour(wxColour(0,128,0)); m_pbtnBits->SetToggle(true, wxT("16"), wxT("24"), 40); @@ -66,45 +67,47 @@ pnlAoipManual::pnlAoipManual(wxWindow* parent,wxWindowID id,const wxPoint& pos,c m_pLbl4->GetUiRect().SetGradient(0); m_pLbl4->SetForegroundColour(wxColour(255,255,255)); m_pLbl4->SetBackgroundColour(wxColour(64,0,128)); - m_plstChannels = new wmList(this, ID_M_PLST5, wxPoint(110,105), wxSize(480,40), wmList::STYLE_SELECT, 0, wxSize(-1,-1), 8, wxSize(5,0)); - m_plstChannels->SetBackgroundColour(wxColour(0,0,0)); - m_plstChannels->SetButtonColour(wxColour(wxT("#004040"))); - m_plstChannels->SetSelectedButtonColour(wxColour(wxT("#FF8000"))); + m_pbtnChannels = new wmButton(this, ID_M_PBTN2, _("2"), wxPoint(110,105), wxSize(92,40), wmButton::STYLE_NORMAL, wxDefaultValidator, _T("ID_M_PBTN2")); + m_pbtnChannels->SetForegroundColour(wxColour(0,0,0)); + m_pbtnChannels->SetBackgroundColour(wxColour(255,255,255)); + m_pbtnChannels->SetColourDisabled(wxColour(wxT("#B0B0B0"))); m_pkbd = new wmKeyboard(this, ID_M_PKBD2, wxPoint(10,160), wxSize(240,200), 5, 0); m_pkbd->SetForegroundColour(wxColour(255,255,255)); wxFont m_pkbdFont(10,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_T("Arial"),wxFONTENCODING_DEFAULT); m_pkbd->SetFont(m_pkbdFont); - m_pbtnStream = new wmButton(this, ID_M_PBTN3, _("Receive"), wxPoint(300,320), wxSize(268,40), wmButton::STYLE_SELECT, wxDefaultValidator, _T("ID_M_PBTN3")); + m_pbtnStream = new wmButton(this, ID_M_PBTN3, _("Receive"), wxPoint(260,161), wxSize(268,40), wmButton::STYLE_SELECT, wxDefaultValidator, _T("ID_M_PBTN3")); m_pbtnStream->SetBackgroundColour(wxColour(0,128,0)); m_pbtnStream->SetToggle(true, wxT("Stop"), wxT("Start"), 40); - m_pLbl8 = new wmLabel(this, ID_M_PLBL11, _("RTPMap"), wxPoint(300,210), wxSize(70,40), 0, _T("ID_M_PLBL11")); + m_pLbl8 = new wmLabel(this, ID_M_PLBL11, _("RTP Payload"), wxPoint(260,105), wxSize(70,40), 0, _T("ID_M_PLBL11")); m_pLbl8->SetBorderState(uiRect::BORDER_NONE); m_pLbl8->GetUiRect().SetGradient(0); m_pLbl8->SetForegroundColour(wxColour(255,255,255)); m_pLbl8->SetBackgroundColour(wxColour(64,0,128)); - m_pbtnRtpMap = new wmButton(this, ID_M_PBTN4, _("96"), wxPoint(370,210), wxSize(80,40), wmButton::STYLE_NORMAL, wxDefaultValidator, _T("ID_M_PBTN4")); + m_pbtnRtpMap = new wmButton(this, ID_M_PBTN4, _("96"), wxPoint(330,105), wxSize(80,40), wmButton::STYLE_NORMAL, wxDefaultValidator, _T("ID_M_PBTN4")); m_pbtnRtpMap->SetForegroundColour(wxColour(0,0,0)); m_pbtnRtpMap->SetBackgroundColour(wxColour(255,255,255)); + m_pbtnRtpMap->SetColourDisabled(wxColour(wxT("#B0B0B0"))); Connect(ID_M_PBTN6,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlAoipManual::OnbtnSampleRateClick); + Connect(ID_M_PBTN2,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlAoipManual::OnbtnChannelsClick); Connect(ID_M_PBTN3,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlAoipManual::OnbtnStreamClick); Connect(ID_M_PBTN4,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlAoipManual::OnbtnRtpMapClick); //*) SetSize(size); SetPosition(pos); - for(int i = 1; i < 9; i++) - { - m_plstChannels->AddButton(wxString::Format("%d", i)); - } + Connect(m_pbtnBits->GetId(),wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlAoipManual::OnbtnBitsClick); + Connect(m_pipServer->GetId(), wxEVT_IPEDIT_CHANGE, (wxObjectEventFunction)&pnlAoipManual::OnIpChanged); + Connect(m_pedtPort->GetId(),wxEVT_COMMAND_TEXT_UPDATED,(wxObjectEventFunction)&pnlAoipManual::OnedtRTPPort); - m_pipServer->SetValue(Settings::Get().Read("ManualAoip", "Source", "")); + m_pipServer->SetValue(Settings::Get().Read("ManualAoip", "Source", "0.0.0.0")); m_pedtPort->SetValue(Settings::Get().Read("ManualAoip", "Port", "5004")); m_pbtnSampleRate->SetLabel(Settings::Get().Read("ManualAoip", "SampleRate", "48000")); m_pbtnBits->ToggleSelection(Settings::Get().Read("ManualAoip", "Bits", 24) == 24); - m_plstChannels->SelectButton(Settings::Get().Read("ManualAoip", "Channels", "2")); + m_pbtnRtpMap->SetLabel(Settings::Get().Read("ManualAoip", "RtpMap", "96")); + m_pbtnChannels->SetLabel(Settings::Get().Read("ManualAoip", "Channels", "2")); + - Connect(m_plstChannels->GetId(), wxEVT_LIST_SELECTED, (wxObjectEventFunction)&pnlAoipManual::OnlstChannelSelected); } pnlAoipManual::~pnlAoipManual() @@ -126,21 +129,20 @@ void pnlAoipManual::OnbtnSampleRateClick(wxCommandEvent& event) { m_pbtnSampleRate->SetLabel(aDlg.m_sSelected); m_pipServer->SetFocus(); + Settings::Get().Write("ManualAoip", "SampleRate", aDlg.m_sSelected); } } -void pnlAoipManual::OnlstChannelSelected(wxCommandEvent& event) -{ - m_sChannels = event.GetString(); -} void pnlAoipManual::OnbtnStreamClick(wxCommandEvent& event) { m_pbtnBits->Enable(event.IsChecked() == false); - m_plstChannels->Enable(event.IsChecked() == false); + m_pbtnChannels->Enable(event.IsChecked() == false); + m_pbtnRtpMap->Enable(event.IsChecked() == false); m_pipServer->Enable(event.IsChecked() == false); m_pkbd->Enable(event.IsChecked() == false); m_pedtPort->Enable(event.IsChecked() == false); + m_pbtnSampleRate->Enable(event.IsChecked() == false); if(event.IsChecked()) { @@ -152,7 +154,7 @@ void pnlAoipManual::OnbtnStreamClick(wxCommandEvent& event) << "a=recvonly\r\n" << "m=audio " << m_pedtPort->GetValue() << " RTP/AVP " << m_pbtnRtpMap->GetLabel() << "\r\n" << "c=IN IP4 " << m_pipServer->GetValue() << "/255\r\n" - << "a=rtpmap:" << m_pbtnRtpMap->GetLabel() <<" L" << (m_pbtnBits->IsChecked() ? "24" : "16") << "/" << m_pbtnSampleRate->GetLabel() << "/" << m_sChannels << "\r\n" + << "a=rtpmap:" << m_pbtnRtpMap->GetLabel() <<" L" << (m_pbtnBits->IsChecked() ? "24" : "16") << "/" << m_pbtnSampleRate->GetLabel() << "/" << m_pbtnChannels->GetLabel() << "\r\n" << "a=mediaclk:direct=0\r\n"; //@todo grandmaster if we have one @@ -170,6 +172,11 @@ void pnlAoipManual::OnbtnStreamClick(wxCommandEvent& event) } } +void pnlAoipManual::OnbtnBitsClick(wxCommandEvent& event) +{ + Settings::Get().Write("ManualAoip", "Bits", event.IsChecked() ? "24" : "16"); +} + void pnlAoipManual::OnbtnRtpMapClick(wxCommandEvent& event) { wxArrayString asButtons; @@ -182,5 +189,32 @@ void pnlAoipManual::OnbtnRtpMapClick(wxCommandEvent& event) if(aDlg.ShowModal()== wxID_OK) { m_pbtnRtpMap->SetLabel(aDlg.m_sSelected); + Settings::Get().Write("ManualAoip", "RtpMap", aDlg.m_sSelected); } } + +void pnlAoipManual::OnbtnChannelsClick(wxCommandEvent& event) +{ + wxArrayString asButtons; + for(int i = 1; i < 9; i++) + { + asButtons.Add(wxString::Format("%d", i)); + } + + dlgMask aDlg(this, asButtons, m_pbtnChannels->GetLabel(), wxNewId(), ClientToScreen(m_pbtnChannels->GetPosition()), m_pbtnChannels->GetSize()); + if(aDlg.ShowModal()== wxID_OK) + { + m_pbtnChannels->SetLabel(aDlg.m_sSelected); + Settings::Get().Write("ManualAoip", "Channels", aDlg.m_sSelected); + } +} + +void pnlAoipManual::OnIpChanged(wxCommandEvent& event) +{ + Settings::Get().Write("ManualAoip", "Source", event.GetString()); +} + +void pnlAoipManual::OnedtRTPPort(wxCommandEvent& event) +{ + Settings::Get().Write("ManualAoip", "Port", m_pedtPort->GetValue()); +} diff --git a/pam2/pnlAoipManual.h b/pam2/pnlAoipManual.h index 3f7ed723..829d8629 100644 --- a/pam2/pnlAoipManual.h +++ b/pam2/pnlAoipManual.h @@ -7,7 +7,6 @@ #include "wmipeditpnl.h" #include "wmkeyboard.h" #include "wmlabel.h" -#include "wmlist.h" #include //*) @@ -20,6 +19,7 @@ class pnlAoipManual: public wxPanel //(*Declarations(pnlAoipManual) wmButton* m_pbtnBits; + wmButton* m_pbtnChannels; wmButton* m_pbtnRtpMap; wmButton* m_pbtnSampleRate; wmButton* m_pbtnStream; @@ -31,7 +31,6 @@ class pnlAoipManual: public wxPanel wmLabel* m_pLbl4; wmLabel* m_pLbl8; wmLabel* m_pLbl9; - wmList* m_plstChannels; //*) protected: @@ -45,7 +44,7 @@ class pnlAoipManual: public wxPanel static const long ID_M_PBTN6; static const long ID_M_PBTN1; static const long ID_M_PLBL4; - static const long ID_M_PLST5; + static const long ID_M_PBTN2; static const long ID_M_PKBD2; static const long ID_M_PBTN3; static const long ID_M_PLBL11; @@ -58,10 +57,13 @@ class pnlAoipManual: public wxPanel void OnbtnSampleRateClick(wxCommandEvent& event); void OnbtnStreamClick(wxCommandEvent& event); void OnbtnRtpMapClick(wxCommandEvent& event); + void OnbtnChannelsClick(wxCommandEvent& event); //*) - void OnlstChannelSelected(wxCommandEvent& event); + void OnbtnBitsClick(wxCommandEvent& event); + void OnIpChanged(wxCommandEvent& event); + void OnedtRTPPort(wxCommandEvent& event); + - wxString m_sChannels; DECLARE_EVENT_TABLE() }; diff --git a/pam2/pnlSettings.cpp b/pam2/pnlSettings.cpp index 33fa39fd..edbe4e31 100644 --- a/pam2/pnlSettings.cpp +++ b/pam2/pnlSettings.cpp @@ -33,7 +33,7 @@ #include "dlgAoIP.h" #include "settingevent.h" #include "aoipsourcemanager.h" - +#include "log.h" #ifdef __NMOS__ #include "nmos.h" #endif // __NMOS__ @@ -268,6 +268,7 @@ pnlSettings::pnlSettings(wxWindow* parent,wxWindowID id,const wxPoint& pos,const Settings::Get().AddHandler("NMOS", "Node", this); + Settings::Get().AddHandler("Input", "AoIP", this); Connect(wxID_ANY, wxEVT_SETTING_CHANGED, (wxObjectEventFunction)&pnlSettings::OnSettingChanged); @@ -296,12 +297,24 @@ void pnlSettings::UpdateDisplayedSettings() void pnlSettings::OnSettingChanged(SettingEvent& event) { + bool bNmos = false; #ifdef __NMOS__ if(event.GetSection().CmpNoCase("NMOS") == 0 && event.GetKey() == "Node") { + bNmos = (event.GetValue(0L) != NmosManager::NODE_OFF) && (event.GetValue(0L) != NmosManager::NODE_SENDER); EnableInputButtons(event.GetValue(0L)); } #endif + if(event.GetSection().CmpNoCase("Input") == 0 && event.GetKey() == "AoIP") + { + if(!bNmos) + { + for(size_t i = 0; i < m_plstInput->GetItemCount(); i++) + { + m_plstInput->EnableButton(i, (event.GetValue(0L) == 0 && i!=m_nNmosButton)); + } + } + } } void pnlSettings::EnableInputButtons(int nMode) @@ -400,6 +413,7 @@ void pnlSettings::ShowRTPDefined() m_plstDevices->Freeze(); m_plstDevices->Clear(); + m_plstDevices->AddButton("OFF", wxNullBitmap, (void*)0); for(auto pairSource : AoipSourceManager::Get().GetSources()) { if(pairSource.first > 0) @@ -472,6 +486,7 @@ void pnlSettings::RefreshInputs() } else if(sType == "AoIP Manual") { + Settings::Get().Write("Input", "AoIP", 0); //just gone on to this screen so disable the incoming stream m_pswpInput->ChangeSelection(1); ShowGain(false); diff --git a/pam2/pnlSettingsOutput.cpp b/pam2/pnlSettingsOutput.cpp index 4816314d..d7c8afd4 100644 --- a/pam2/pnlSettingsOutput.cpp +++ b/pam2/pnlSettingsOutput.cpp @@ -33,17 +33,21 @@ const long pnlSettingsOutput::ID_M_PBTN6 = wxNewId(); const long pnlSettingsOutput::ID_M_PLBL6 = wxNewId(); const long pnlSettingsOutput::ID_M_PEDT3 = wxNewId(); const long pnlSettingsOutput::ID_M_PLBL7 = wxNewId(); -const long pnlSettingsOutput::ID_M_PLST5 = wxNewId(); +const long pnlSettingsOutput::ID_M_PBTN7 = wxNewId(); const long pnlSettingsOutput::ID_M_PEDT2 = wxNewId(); -const long pnlSettingsOutput::ID_M_PBTN1 = wxNewId(); +const long pnlSettingsOutput::ID_M_PBTN12 = wxNewId(); const long pnlSettingsOutput::ID_M_PBTN2 = wxNewId(); const long pnlSettingsOutput::ID_M_PKBD2 = wxNewId(); const long pnlSettingsOutput::ID_M_PLBL9 = wxNewId(); const long pnlSettingsOutput::ID_M_PBTN8 = wxNewId(); const long pnlSettingsOutput::ID_M_PBTN9 = wxNewId(); const long pnlSettingsOutput::ID_M_PBTN3 = wxNewId(); +const long pnlSettingsOutput::ID_M_PBTN1 = wxNewId(); const long pnlSettingsOutput::ID_M_PLBL12 = wxNewId(); const long pnlSettingsOutput::ID_M_PBTN5 = wxNewId(); +const long pnlSettingsOutput::ID_M_PLBL13 = wxNewId(); +const long pnlSettingsOutput::ID_M_PBTN10 = wxNewId(); +const long pnlSettingsOutput::ID_M_PBTN11 = wxNewId(); const long pnlSettingsOutput::ID_M_PLBL11 = wxNewId(); const long pnlSettingsOutput::ID_M_PBTN4 = wxNewId(); const long pnlSettingsOutput::ID_PANEL11 = wxNewId(); @@ -107,7 +111,7 @@ pnlSettingsOutput::pnlSettingsOutput(wxWindow* parent,wxWindowID id,const wxPoin m_plblOutputGain->SetFont(m_plblOutputGainFont); pnlAoip = new wxPanel(m_pswpDestination, ID_PANEL11, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T("ID_PANEL11")); pnlAoip->SetBackgroundColour(wxColour(0,0,0)); - m_pLbl1 = new wmLabel(pnlAoip, ID_M_PLBL1, _("Multicast"), wxPoint(0,55), wxSize(100,40), 0, _T("ID_M_PLBL1")); + m_pLbl1 = new wmLabel(pnlAoip, ID_M_PLBL1, _("Destination"), wxPoint(0,55), wxSize(100,40), 0, _T("ID_M_PLBL1")); m_pLbl1->SetBorderState(uiRect::BORDER_NONE); m_pLbl1->GetUiRect().SetGradient(0); m_pLbl1->SetForegroundColour(wxColour(255,255,255)); @@ -125,9 +129,10 @@ pnlSettingsOutput::pnlSettingsOutput(wxWindow* parent,wxWindowID id,const wxPoin m_pLbl9->GetUiRect().SetGradient(0); m_pLbl9->SetForegroundColour(wxColour(255,255,255)); m_pLbl9->SetBackgroundColour(wxColour(64,0,128)); - m_pbtnRTSP = new wmButton(pnlAoip, ID_M_PBTN6, _("Stream"), wxPoint(100,10), wxSize(200,40), wmButton::STYLE_NORMAL, wxDefaultValidator, _T("ID_M_PBTN6")); + m_pbtnRTSP = new wmButton(pnlAoip, ID_M_PBTN6, _("eth0"), wxPoint(100,10), wxSize(200,40), wmButton::STYLE_NORMAL, wxDefaultValidator, _T("ID_M_PBTN6")); m_pbtnRTSP->SetForegroundColour(wxColour(0,0,0)); m_pbtnRTSP->SetBackgroundColour(wxColour(255,255,255)); + m_pbtnRTSP->SetColourDisabled(wxColour(wxT("#B0B0B0"))); m_pLbl6 = new wmLabel(pnlAoip, ID_M_PLBL6, _("Port"), wxPoint(300,10), wxSize(50,40), 0, _T("ID_M_PLBL6")); m_pLbl6->SetBorderState(uiRect::BORDER_NONE); m_pLbl6->GetUiRect().SetGradient(0); @@ -136,62 +141,81 @@ pnlSettingsOutput::pnlSettingsOutput(wxWindow* parent,wxWindowID id,const wxPoin m_pedtRTSPPort = new wmEdit(pnlAoip, ID_M_PEDT3, wxEmptyString, wxPoint(350,10), wxSize(100,40), 0, wxDefaultValidator, _T("ID_M_PEDT3")); m_pedtRTSPPort->SetValidation(4); m_pedtRTSPPort->SetBorderStyle(1,1); - m_pLbl7 = new wmLabel(pnlAoip, ID_M_PLBL7, _("Packet Time"), wxPoint(0,100), wxSize(100,40), 0, _T("ID_M_PLBL7")); + m_pLbl7 = new wmLabel(pnlAoip, ID_M_PLBL7, _("Packet Time"), wxPoint(0,110), wxSize(100,40), 0, _T("ID_M_PLBL7")); m_pLbl7->SetBorderState(uiRect::BORDER_NONE); m_pLbl7->GetUiRect().SetGradient(0); m_pLbl7->SetForegroundColour(wxColour(255,255,255)); m_pLbl7->SetBackgroundColour(wxColour(64,0,128)); - m_plstPacket = new wmList(pnlAoip, ID_M_PLST5, wxPoint(105,99), wxSize(490,44), wmList::STYLE_SELECT, 0, wxSize(-1,-1), 5, wxSize(5,-1)); - m_plstPacket->SetBackgroundColour(wxColour(0,0,0)); - m_plstPacket->SetButtonColour(wxColour(wxT("#004040"))); - m_plstPacket->SetSelectedButtonColour(wxColour(wxT("#FF8000"))); + m_pbtnPacketTime = new wmButton(pnlAoip, ID_M_PBTN7, _("1 ms"), wxPoint(100,110), wxSize(70,40), wmButton::STYLE_NORMAL, wxDefaultValidator, _T("ID_M_PBTN7")); + m_pbtnPacketTime->SetForegroundColour(wxColour(0,0,0)); + m_pbtnPacketTime->SetBackgroundColour(wxColour(255,255,255)); + m_pbtnPacketTime->SetColourDisabled(wxColour(wxT("#B0B0B0"))); m_pedtRTPPort = new wmEdit(pnlAoip, ID_M_PEDT2, wxEmptyString, wxPoint(350,55), wxSize(100,40), 0, wxDefaultValidator, _T("ID_M_PEDT2")); m_pedtRTPPort->SetValidation(4); m_pedtRTPPort->SetBorderStyle(1,1); - m_pbtnRestartStream = new wmButton(pnlAoip, ID_M_PBTN1, _("Restart Stream"), wxPoint(470,10), wxSize(120,40), wmButton::STYLE_HOLD, wxDefaultValidator, _T("ID_M_PBTN1")); - m_pbtnRestartStream->SetBackgroundColour(wxColour(255,0,0)); - wxFont m_pbtnRestartStreamFont(12,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL,false,_T("Tahoma"),wxFONTENCODING_DEFAULT); - m_pbtnRestartStream->SetFont(m_pbtnRestartStreamFont); - m_pbtnStats = new wmButton(pnlAoip, ID_M_PBTN2, _("RTCP Stats"), wxPoint(470,55), wxSize(120,40), 0, wxDefaultValidator, _T("ID_M_PBTN2")); + m_pbtnRTCP = new wmButton(pnlAoip, ID_M_PBTN12, _("RTCP"), wxPoint(455,55), wxSize(135,40), wmButton::STYLE_SELECT, wxDefaultValidator, _T("ID_M_PBTN12")); + m_pbtnRTCP->SetBackgroundColour(wxColour(0,128,0)); + m_pbtnRTCP->SetToggle(true, wxT("Off"), wxT("On"), 50); + m_pbtnStats = new wmButton(pnlAoip, ID_M_PBTN2, _("RTCP Stats"), wxPoint(358,255), wxSize(135,35), 0, wxDefaultValidator, _T("ID_M_PBTN2")); m_pbtnStats->SetBackgroundColour(wxColour(64,128,128)); wxFont m_pbtnStatsFont(12,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL,false,_T("Tahoma"),wxFONTENCODING_DEFAULT); m_pbtnStats->SetFont(m_pbtnStatsFont); - m_pkbd = new wmKeyboard(pnlAoip, ID_M_PKBD2, wxPoint(10,160), wxSize(240,200), 5, 0); + m_pkbd = new wmKeyboard(pnlAoip, ID_M_PKBD2, wxPoint(10,174), wxSize(240,200), 5, 0); m_pkbd->SetForegroundColour(wxColour(255,255,255)); wxFont m_pkbdFont(10,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_T("Arial"),wxFONTENCODING_DEFAULT); m_pkbd->SetFont(m_pkbdFont); - m_pLbl10 = new wmLabel(pnlAoip, ID_M_PLBL9, _("Advertise"), wxPoint(260,250), wxSize(330,30), 0, _T("ID_M_PLBL9")); + m_pLbl10 = new wmLabel(pnlAoip, ID_M_PLBL9, _("Advertise"), wxPoint(260,295), wxSize(330,30), 0, _T("ID_M_PLBL9")); m_pLbl10->SetBorderState(uiRect::BORDER_NONE); m_pLbl10->GetUiRect().SetGradient(0); m_pLbl10->SetForegroundColour(wxColour(255,255,255)); m_pLbl10->SetBackgroundColour(wxColour(61,120,218)); wxFont m_pLbl10Font(10,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,wxEmptyString,wxFONTENCODING_DEFAULT); m_pLbl10->SetFont(m_pLbl10Font); - m_pbtnDNS = new wmButton(pnlAoip, ID_M_PBTN8, _("mDNS-SD"), wxPoint(300,285), wxSize(268,40), wmButton::STYLE_SELECT, wxDefaultValidator, _T("ID_M_PBTN8")); + m_pbtnDNS = new wmButton(pnlAoip, ID_M_PBTN8, _("mDNS-SD"), wxPoint(260,330), wxSize(160,40), wmButton::STYLE_SELECT, wxDefaultValidator, _T("ID_M_PBTN8")); m_pbtnDNS->SetBackgroundColour(wxColour(61,120,218)); - m_pbtnDNS->SetToggle(true, wxT("Off"), wxT("On"), 40); - m_pbtnSAP = new wmButton(pnlAoip, ID_M_PBTN9, _("SAP"), wxPoint(300,330), wxSize(268,40), wmButton::STYLE_SELECT, wxDefaultValidator, _T("ID_M_PBTN9")); + m_pbtnDNS->SetToggle(true, wxT("Off"), wxT("On"), 60); + m_pbtnSAP = new wmButton(pnlAoip, ID_M_PBTN9, _("SAP"), wxPoint(430,330), wxSize(160,40), wmButton::STYLE_SELECT, wxDefaultValidator, _T("ID_M_PBTN9")); m_pbtnSAP->SetBackgroundColour(wxColour(61,120,218)); - m_pbtnSAP->SetToggle(true, wxT("Off"), wxT("On"), 40); - m_pbtnStream = new wmButton(pnlAoip, ID_M_PBTN3, _("Stream"), wxPoint(300,200), wxSize(268,40), wmButton::STYLE_SELECT, wxDefaultValidator, _T("ID_M_PBTN3")); + m_pbtnSAP->SetToggle(true, wxT("Off"), wxT("On"), 60); + m_pbtnStream = new wmButton(pnlAoip, ID_M_PBTN3, _("Stream"), wxPoint(260,175), wxSize(330,35), wmButton::STYLE_SELECT, wxDefaultValidator, _T("ID_M_PBTN3")); m_pbtnStream->SetBackgroundColour(wxColour(0,128,0)); - m_pbtnStream->SetToggle(true, wxT("Unicast"), wxT("Multicast"), 40); - m_pLbl11 = new wmLabel(pnlAoip, ID_M_PLBL12, _("Channels"), wxPoint(300,145), wxSize(70,40), 0, _T("ID_M_PLBL12")); + m_pbtnStream->SetToggle(true, wxT("On Demand"), wxT("Always On"), 40); + m_pbtnActive = new wmButton(pnlAoip, ID_M_PBTN1, _("Server"), wxPoint(260,215), wxSize(330,35), wmButton::STYLE_SELECT, wxDefaultValidator, _T("ID_M_PBTN1")); + m_pbtnActive->SetBackgroundColour(wxColour(0,128,0)); + m_pbtnActive->SetToggle(true, wxT("Inactive"), wxT("Active"), 40); + m_pLbl11 = new wmLabel(pnlAoip, ID_M_PLBL12, _("Channels"), wxPoint(172,110), wxSize(60,40), 0, _T("ID_M_PLBL12")); m_pLbl11->SetBorderState(uiRect::BORDER_NONE); m_pLbl11->GetUiRect().SetGradient(0); m_pLbl11->SetForegroundColour(wxColour(255,255,255)); m_pLbl11->SetBackgroundColour(wxColour(64,0,128)); - m_pbtnChannels = new wmButton(pnlAoip, ID_M_PBTN5, _("2"), wxPoint(370,145), wxSize(60,40), wmButton::STYLE_NORMAL, wxDefaultValidator, _T("ID_M_PBTN5")); + m_pbtnChannels = new wmButton(pnlAoip, ID_M_PBTN5, _("2"), wxPoint(232,110), wxSize(50,40), wmButton::STYLE_NORMAL, wxDefaultValidator, _T("ID_M_PBTN5")); m_pbtnChannels->SetForegroundColour(wxColour(0,0,0)); m_pbtnChannels->SetBackgroundColour(wxColour(255,255,255)); - m_pLbl8 = new wmLabel(pnlAoip, ID_M_PLBL11, _("RTPMap"), wxPoint(438,145), wxSize(70,40), 0, _T("ID_M_PLBL11")); + m_pbtnChannels->SetColourDisabled(wxColour(wxT("#B0B0B0"))); + m_pLbl12 = new wmLabel(pnlAoip, ID_M_PLBL13, _("Sample Rate"), wxPoint(284,110), wxSize(60,40), 0, _T("ID_M_PLBL13")); + m_pLbl12->SetBorderState(uiRect::BORDER_NONE); + m_pLbl12->GetUiRect().SetGradient(0); + m_pLbl12->SetForegroundColour(wxColour(255,255,255)); + m_pLbl12->SetBackgroundColour(wxColour(64,0,128)); + m_pbtnSampleRate = new wmButton(pnlAoip, ID_M_PBTN10, _("48 kHz"), wxPoint(344,110), wxSize(70,40), wmButton::STYLE_NORMAL, wxDefaultValidator, _T("ID_M_PBTN10")); + m_pbtnSampleRate->Disable(); + m_pbtnSampleRate->SetForegroundColour(wxColour(0,0,0)); + m_pbtnSampleRate->SetBackgroundColour(wxColour(255,255,255)); + m_pbtnSampleRate->SetColourDisabled(wxColour(wxT("#B0B0B0"))); + m_pbtnBits = new wmButton(pnlAoip, ID_M_PBTN11, _("Bits"), wxPoint(416,110), wxSize(174,40), wmButton::STYLE_SELECT, wxDefaultValidator, _T("ID_M_PBTN11")); + m_pbtnBits->Disable(); + m_pbtnBits->SetBackgroundColour(wxColour(0,128,0)); + m_pbtnBits->SetColourDisabled(wxColour(wxT("#606060"))); + m_pbtnBits->SetToggle(true, wxT("16"), wxT("24"), 50); + m_pLbl8 = new wmLabel(pnlAoip, ID_M_PLBL11, _("RTP Payload"), wxPoint(455,10), wxSize(70,40), 0, _T("ID_M_PLBL11")); m_pLbl8->SetBorderState(uiRect::BORDER_NONE); m_pLbl8->GetUiRect().SetGradient(0); m_pLbl8->SetForegroundColour(wxColour(255,255,255)); m_pLbl8->SetBackgroundColour(wxColour(64,0,128)); - m_pbtnRtpMap = new wmButton(pnlAoip, ID_M_PBTN4, _("96"), wxPoint(508,145), wxSize(60,40), wmButton::STYLE_NORMAL, wxDefaultValidator, _T("ID_M_PBTN4")); + m_pbtnRtpMap = new wmButton(pnlAoip, ID_M_PBTN4, _("96"), wxPoint(525,10), wxSize(65,40), wmButton::STYLE_NORMAL, wxDefaultValidator, _T("ID_M_PBTN4")); m_pbtnRtpMap->SetForegroundColour(wxColour(0,0,0)); m_pbtnRtpMap->SetBackgroundColour(wxColour(255,255,255)); + m_pbtnRtpMap->SetColourDisabled(wxColour(wxT("#B0B0B0"))); m_pswpDestination->AddPage(pnlDisabled, _("Disabled"), false); m_pswpDestination->AddPage(pnlSoundcard, _("Soundcard"), false); m_pswpDestination->AddPage(pnlAoip, _("AoIP"), false); @@ -202,28 +226,29 @@ pnlSettingsOutput::pnlSettingsOutput(wxWindow* parent,wxWindowID id,const wxPoin Connect(ID_M_PSLIDER1,wxEVT_SLIDER_MOVE,(wxObjectEventFunction)&pnlSettingsOutput::OnlsliderOutputGainMove); Connect(ID_M_PBTN6,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlSettingsOutput::OnbtnRTSPClick); Connect(ID_M_PEDT3,wxEVT_COMMAND_TEXT_UPDATED,(wxObjectEventFunction)&pnlSettingsOutput::OnedtRTSPPortText); - Connect(ID_M_PLST5,wxEVT_LIST_SELECTED,(wxObjectEventFunction)&pnlSettingsOutput::OnlstPacketSelected); + Connect(ID_M_PBTN7,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlSettingsOutput::OnbtnPacketTimeClick); Connect(ID_M_PEDT2,wxEVT_COMMAND_TEXT_UPDATED,(wxObjectEventFunction)&pnlSettingsOutput::OnedtRTPPortText); - Connect(ID_M_PBTN1,wxEVT_BUTTON_HELD,(wxObjectEventFunction)&pnlSettingsOutput::OnbtnRestartStreamHeld); + Connect(ID_M_PBTN12,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlSettingsOutput::OnbtnRTCPClick); Connect(ID_M_PBTN2,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlSettingsOutput::OnbtnStatsClick); Connect(ID_M_PBTN8,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlSettingsOutput::OnbtnDNSClick); Connect(ID_M_PBTN9,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlSettingsOutput::OnbtnSAPClick); Connect(ID_M_PBTN3,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlSettingsOutput::OnbtnStreamClick); + Connect(ID_M_PBTN1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlSettingsOutput::OnbtnActiveClick); Connect(ID_M_PBTN5,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlSettingsOutput::OnbtnChannelsClick); + Connect(ID_M_PBTN10,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlSettingsOutput::OnbtnSampleRateClick); + Connect(ID_M_PBTN11,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlSettingsOutput::OnbtnBitsClick); Connect(ID_M_PBTN4,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&pnlSettingsOutput::OnbtnRtpMapClick); //*) SetSize(size); SetPosition(pos); + m_pbtnBits->SetColourDisabled(wxColour(180,180,180)); + m_pbtnSampleRate->SetColourDisabled(wxColour(180,180,180)); + m_plstDestination->AddButton(wxT("Disabled")); m_plstDestination->AddButton(wxT("Soundcard")); m_plstDestination->AddButton(wxT("AoIP")); - m_plstPacket->AddButton(wxT("125us"), wxNullBitmap, (void*)125); - m_plstPacket->AddButton(wxT("250us"), wxNullBitmap, (void*)250); - m_plstPacket->AddButton(wxT("333us"), wxNullBitmap, (void*)333); - m_plstPacket->AddButton(wxT("1ms"), wxNullBitmap, (void*)1000); - m_plstPacket->AddButton(wxT("4ms"), wxNullBitmap, (void*)4000); for(unsigned int i = 0; i < 10; i++) { @@ -249,6 +274,8 @@ pnlSettingsOutput::pnlSettingsOutput(wxWindow* parent,wxWindowID id,const wxPoin Settings::Get().AddHandler(wxT("Server"), wxT("DNS-SD"), this); Settings::Get().AddHandler(wxT("Server"), wxT("RTPMap"), this); Settings::Get().AddHandler(wxT("Server"), wxT("Channels"), this); + Settings::Get().AddHandler(wxT("Server"), wxT("RTCP"), this); + Settings::Get().AddHandler(wxT("Server"), wxT("State"), this); Connect(wxID_ANY, wxEVT_SETTING_CHANGED, (wxObjectEventFunction)&pnlSettingsOutput::OnSettingChanged); } @@ -263,7 +290,17 @@ pnlSettingsOutput::~pnlSettingsOutput() void pnlSettingsOutput::UpdateDisplayedSettings() { m_plstDestination->SelectButton(Settings::Get().Read(wxT("Output"), wxT("Destination"), wxT("Disabled")), false); - m_plstPacket->SelectButton(m_plstPacket->FindButton(reinterpret_cast(Settings::Get().Read(wxT("Server"), wxT("PacketTime"), 4000)))); + + int nTime = Settings::Get().Read("Server", "PacketTime", 1000); + if(nTime > 999) + { + m_pbtnPacketTime->SetLabel(wxString::Format("%d ms", nTime/1000)); + } + else + { + m_pbtnPacketTime->SetLabel(wxString::Format(L"%d \u00B5s", nTime)); + } + m_pswpDestination->ChangeSelection(Settings::Get().Read(wxT("Output"), wxT("Destination"), wxT("Disabled"))); @@ -275,7 +312,7 @@ void pnlSettingsOutput::UpdateDisplayedSettings() m_plstLatency->SelectButton(Settings::Get().Read(wxT("Output"), wxT("Latency"), 0)/40, false); m_pbtnRTSP->SetLabel(Settings::Get().Read(wxT("Server"), wxT("RTSP_Interface"), wxEmptyString)); - bool bMulticast(Settings::Get().Read(wxT("Server"), wxT("Stream"), "Unicast") == "Multicast"); + bool bMulticast(Settings::Get().Read(wxT("Server"), wxT("Stream"), "OnDemand") == "AlwaysOn"); m_pbtnStream->ToggleSelection(bMulticast); m_pbtnRtpMap->SetLabel(Settings::Get().Read("Server", "RTPMap", "96")); @@ -287,10 +324,19 @@ void pnlSettingsOutput::UpdateDisplayedSettings() m_pbtnDNS->ToggleSelection(Settings::Get().Read("Server", "DNS-SD", 0), true); m_pbtnSAP->ToggleSelection(Settings::Get().Read("Server", "SAP", 0), true); + m_pbtnRTCP->ToggleSelection(Settings::Get().Read("Server", "RTCP", 0), true); + + m_pbtnStats->Show(m_pbtnRTCP->IsChecked()); double dGain = ConvertRatioToGain(Settings::Get().Read("Output", "Ratio_00", 1.0)); m_plblOutputGain->SetLabel(wxString::Format("%.2f dB", dGain)); m_plsliderOutputGain->SetSliderPosition(dGain*500+5000, false); + + m_pbtnBits->ToggleSelection(Settings::Get().Read("Server", "Bits", 24) == 24); + m_pbtnSampleRate->SetLabel(Settings::Get().Read("Server", "SampleRate", "48000")); + + m_pbtnActive->ToggleSelection(Settings::Get().Read("Server", "State", 0) == 1); + EnableStreamSettings(); } @@ -320,7 +366,7 @@ void pnlSettingsOutput::OnSettingChanged(SettingEvent& event) } else if(event.GetKey() == wxT("Stream")) { - bool bMulticast(Settings::Get().Read(wxT("Server"), wxT("Stream"), "Unicast") == "Multicast"); + bool bMulticast(Settings::Get().Read(wxT("Server"), wxT("Stream"), "OnDemand") == "AlwaysOn"); m_pbtnStream->ToggleSelection(bMulticast); m_pbtnSAP->Show(bMulticast); m_pLbl1->Show(bMulticast); @@ -342,12 +388,21 @@ void pnlSettingsOutput::OnSettingChanged(SettingEvent& event) { m_pbtnChannels->SetLabel(event.GetValue()); } + else if(event.GetKey() == "RTCP") + { + m_pbtnStats->Show(event.GetValue(false)); + } + else if(event.GetKey() == "State") + { + m_pbtnActive->ToggleSelection(event.GetValue(false), false); + EnableStreamSettings(); + } } } void pnlSettingsOutput::OnlstDestinationSelected(wxCommandEvent& event) { - Settings::Get().Write(wxT("Output"), wxT("Destination"), event.GetString()); + Settings::Get().Write(wxT("Output"), wxT("Destination"), event.GetString()); m_plstPlayback->Enable(event.GetString()!=wxT("Disabled")); m_pswpDestination->ChangeSelection(event.GetString()); } @@ -364,20 +419,14 @@ void pnlSettingsOutput::OnbtnStreamClick(wxCommandEvent& event) if(event.IsChecked() == false) { - Settings::Get().Write(wxT("Server"), wxT("Stream"), "Unicast"); + Settings::Get().Write(wxT("Server"), wxT("Stream"), "OnDemand"); } else { //@todo create the new session Settings::Get().Write(wxT("Server"), wxT("DestinationIp"), m_ppnlAddress->GetValue()); - Settings::Get().Write(wxT("Server"), wxT("Stream"), "Multicast"); + Settings::Get().Write(wxT("Server"), wxT("Stream"), "AlwaysOn"); } - /*m_ppnlAddress->Enable((event.IsChecked() == false)); - m_pedtRTSPPort->Enable((event.IsChecked() == false)); - m_pedtRTPPort->Enable((event.IsChecked() == false)); - m_plstPacket->Enable((event.IsChecked() == false)); - m_pkbd->Enable((event.IsChecked() == false));*/ - } void pnlSettingsOutput::OnlstPacketSelected(wxCommandEvent& event) @@ -487,7 +536,6 @@ double pnlSettingsOutput::ConvertRatioToGain(double dRatio) void pnlSettingsOutput::OnbtnRestartStreamHeld(wxCommandEvent& event) { - IOManager::Get().RestartStream(); } void pnlSettingsOutput::OnbtnStatsClick(wxCommandEvent& event) @@ -527,3 +575,79 @@ void pnlSettingsOutput::OnbtnChannelsClick(wxCommandEvent& event) Settings::Get().Write("Server", "Channels", aDlg.m_sSelected); } } + +void pnlSettingsOutput::OnbtnPacketTimeClick(wxCommandEvent& event) +{ + wxArrayString asButtons; + asButtons.Add(L"125 \u00B5s"); + asButtons.Add(L"250 \u00B5s"); + asButtons.Add(L"333 \u00B5s"); + asButtons.Add("1 ms"); + asButtons.Add("4 ms"); + + + dlgMask aDlg(this, asButtons, m_pbtnPacketTime->GetLabel(), wxNewId(), ClientToScreen(m_pbtnPacketTime->GetPosition()), m_pbtnPacketTime->GetSize()); + if(aDlg.ShowModal()== wxID_OK) + { + m_pbtnPacketTime->SetLabel(aDlg.m_sSelected); + unsigned long nTime; + aDlg.m_sSelected.Before(' ').ToULong(&nTime); + if(nTime == 1 || nTime == 4) + { + nTime*=1000; + } + Settings::Get().Write("Server", "PacketTime", (int)nTime); + } +} + +void pnlSettingsOutput::OnbtnSampleRateClick(wxCommandEvent& event) +{ + wxArrayString asButtons; + asButtons.Add("44100"); + asButtons.Add("48000"); + asButtons.Add("96000"); + + dlgMask aDlg(this, asButtons, m_pbtnSampleRate->GetLabel(), wxNewId(), ClientToScreen(m_pbtnSampleRate->GetPosition()), m_pbtnSampleRate->GetSize()); + if(aDlg.ShowModal()== wxID_OK) + { + m_pbtnSampleRate->SetLabel(aDlg.m_sSelected); + unsigned long nSampleRate; + aDlg.m_sSelected.ToULong(&nSampleRate); + Settings::Get().Write("Server", "SampleRate", (int)nSampleRate); + } +} + +void pnlSettingsOutput::OnbtnBitsClick(wxCommandEvent& event) +{ + Settings::Get().Write("Server", "Bits", event.IsChecked() ? 24 : 16); +} + +void pnlSettingsOutput::OnbtnRTCPClick(wxCommandEvent& event) +{ + Settings::Get().Write("Server", "RTCP", event.IsChecked() ? 1 : 0); +} + +void pnlSettingsOutput::OnbtnActiveClick(wxCommandEvent& event) +{ + Settings::Get().Write("Server", "State", event.IsChecked() ? "1" : "0"); + EnableStreamSettings(); +} + +void pnlSettingsOutput::EnableStreamSettings() +{ + m_ppnlAddress->Enable(!m_pbtnActive->IsChecked()); + m_pbtnRTSP->Enable(!m_pbtnActive->IsChecked()); + m_pedtRTSPPort->Enable(!m_pbtnActive->IsChecked()); + m_pbtnPacketTime->Enable(!m_pbtnActive->IsChecked()); + m_pedtRTPPort->Enable(!m_pbtnActive->IsChecked()); + m_pbtnRTCP->Enable(!m_pbtnActive->IsChecked()); + m_pbtnStats->Enable(m_pbtnActive->IsChecked()); + m_pbtnDNS->Enable(!m_pbtnActive->IsChecked()); + m_pbtnSAP->Enable(!m_pbtnActive->IsChecked()); + m_pbtnChannels->Enable(!m_pbtnActive->IsChecked()); + m_pbtnRtpMap->Enable(!m_pbtnActive->IsChecked()); + m_pbtnStream->Enable(!m_pbtnActive->IsChecked()); + + //m_pbtnSampleRate->Enable(!m_pbtnActive->IsChecked()); + //m_pbtnBits->Enable(!m_pbtnActive->IsChecked()); +} diff --git a/pam2/pnlSettingsOutput.h b/pam2/pnlSettingsOutput.h index 26f41c68..be6b1ee0 100644 --- a/pam2/pnlSettingsOutput.h +++ b/pam2/pnlSettingsOutput.h @@ -27,12 +27,16 @@ class pnlSettingsOutput: public wxPanel void ShowSoundcardOutputs(); //(*Declarations(pnlSettingsOutput) + wmButton* m_pbtnActive; + wmButton* m_pbtnBits; wmButton* m_pbtnChannels; wmButton* m_pbtnDNS; + wmButton* m_pbtnPacketTime; + wmButton* m_pbtnRTCP; wmButton* m_pbtnRTSP; - wmButton* m_pbtnRestartStream; wmButton* m_pbtnRtpMap; wmButton* m_pbtnSAP; + wmButton* m_pbtnSampleRate; wmButton* m_pbtnStats; wmButton* m_pbtnStream; wmEdit* m_pedtRTPPort; @@ -40,6 +44,7 @@ class pnlSettingsOutput: public wxPanel wmKeyboard* m_pkbd; wmLabel* m_pLbl10; wmLabel* m_pLbl11; + wmLabel* m_pLbl12; wmLabel* m_pLbl1; wmLabel* m_pLbl2; wmLabel* m_pLbl3; @@ -52,7 +57,6 @@ class pnlSettingsOutput: public wxPanel wmLabel* m_plblOutputGain; wmList* m_plstDestination; wmList* m_plstLatency; - wmList* m_plstPacket; wmList* m_plstPlayback; wmSlider* m_plsliderOutputGain; wmSwitcherPanel* m_pswpDestination; @@ -83,17 +87,21 @@ class pnlSettingsOutput: public wxPanel static const long ID_M_PLBL6; static const long ID_M_PEDT3; static const long ID_M_PLBL7; - static const long ID_M_PLST5; + static const long ID_M_PBTN7; static const long ID_M_PEDT2; - static const long ID_M_PBTN1; + static const long ID_M_PBTN12; static const long ID_M_PBTN2; static const long ID_M_PKBD2; static const long ID_M_PLBL9; static const long ID_M_PBTN8; static const long ID_M_PBTN9; static const long ID_M_PBTN3; + static const long ID_M_PBTN1; static const long ID_M_PLBL12; static const long ID_M_PBTN5; + static const long ID_M_PLBL13; + static const long ID_M_PBTN10; + static const long ID_M_PBTN11; static const long ID_M_PLBL11; static const long ID_M_PBTN4; static const long ID_PANEL11; @@ -118,6 +126,11 @@ class pnlSettingsOutput: public wxPanel void OnbtnStatsClick(wxCommandEvent& event); void OnbtnRtpMapClick(wxCommandEvent& event); void OnbtnChannelsClick(wxCommandEvent& event); + void OnbtnPacketTimeClick(wxCommandEvent& event); + void OnbtnSampleRateClick(wxCommandEvent& event); + void OnbtnBitsClick(wxCommandEvent& event); + void OnbtnRTCPClick(wxCommandEvent& event); + void OnbtnActiveClick(wxCommandEvent& event); //*) void OnSettingChanged(SettingEvent& event); @@ -127,6 +140,7 @@ class pnlSettingsOutput: public wxPanel DECLARE_EVENT_TABLE() void UpdateDisplayedSettings(); + void EnableStreamSettings(); }; #endif diff --git a/pam2/wxsmith/pnlAoipManual.wxs b/pam2/wxsmith/pnlAoipManual.wxs index 8a7b1a52..57eab816 100644 --- a/pam2/wxsmith/pnlAoipManual.wxs +++ b/pam2/wxsmith/pnlAoipManual.wxs @@ -36,6 +36,7 @@ + #B0B0B0 Stop Start 50 @@ -64,17 +65,18 @@ #FFFFFF #400080 - - None - 5,0 - 8 - - #FF8000 - + + + #B0B0B0 + Stop + Start + 50 110,105 - 480,40 - #000000 - + 92,40 + #000000 + #FFFFFF + + Calc @@ -96,25 +98,26 @@ Stop Start 40 - 300,320 + 260,161 268,40 #008000 - - 300,210 + + 260,105 70,40 #FFFFFF #400080 + #B0B0B0 Stop Start 50 - 370,210 + 330,105 80,40 #000000 #FFFFFF diff --git a/pam2/wxsmith/pnlSettingsOutput.wxs b/pam2/wxsmith/pnlSettingsOutput.wxs index 31cde277..6e09b3c9 100644 --- a/pam2/wxsmith/pnlSettingsOutput.wxs +++ b/pam2/wxsmith/pnlSettingsOutput.wxs @@ -123,7 +123,7 @@ #000000 - + 0,55 100,40 #FFFFFF @@ -150,7 +150,8 @@ #400080 - + + #B0B0B0 Stop Start 50 @@ -178,23 +179,23 @@ - 0,100 + 0,110 100,40 #FFFFFF #400080 - - None - 5,-1 - 5 - - #FF8000 - - 105,99 - 490,44 - #000000 - - + + + #B0B0B0 + Stop + Start + 50 + 100,110 + 70,40 + #000000 + #FFFFFF + + Integer @@ -204,26 +205,22 @@ 100,40 - - - 470,10 - 120,40 - #FF0000 - - 12 - - normal - 0 - swiss - Tahoma - - - + + + 1 + Off + On + 50 + 455,55 + 135,40 + #008000 + + - 470,55 - 120,40 + 358,255 + 135,35 #408080 12 @@ -237,7 +234,7 @@ Calc - 10,160 + 10,174 240,200 #FFFFFF @@ -251,7 +248,7 @@ - 260,250 + 260,295 330,30 #FFFFFF #3D78DA @@ -268,9 +265,9 @@ 1 Off On - 40 - 300,285 - 268,40 + 60 + 260,330 + 160,40 #3D78DA @@ -280,9 +277,9 @@ 1 Off On - 40 - 300,330 - 268,40 + 60 + 430,330 + 160,40 #3D78DA @@ -290,48 +287,97 @@ 1 - Unicast - Multicast + On Demand + Always On 40 - 300,200 - 268,40 + 260,175 + 330,35 #008000 + + + 1 + Inactive + Active + 40 + 260,215 + 330,35 + #008000 + + + - 300,145 - 70,40 + 172,110 + 60,40 #FFFFFF #400080 + #B0B0B0 Stop Start 50 - 370,145 - 60,40 + 232,110 + 50,40 #000000 #FFFFFF + + + 284,110 + 60,40 + #FFFFFF + #400080 + + + + #B0B0B0 + Stop + Start + 50 + 344,110 + 70,40 + 0 + #000000 + #FFFFFF + + + + + + #606060 + 1 + 16 + 24 + 50 + 416,110 + 174,40 + 0 + #008000 + + + - - 438,145 + + 455,10 70,40 #FFFFFF #400080 + #B0B0B0 Stop Start 50 - 508,145 - 60,40 + 525,10 + 65,40 #000000 #FFFFFF diff --git a/pambase/AES67ServerMediaSubsession.cpp b/pambase/AES67ServerMediaSubsession.cpp index 0167a61e..87ea26c2 100644 --- a/pambase/AES67ServerMediaSubsession.cpp +++ b/pambase/AES67ServerMediaSubsession.cpp @@ -23,7 +23,7 @@ AES67ServerMediaSubsession::AES67ServerMediaSubsession(const std::setsetRRHandler((TaskFunc*)MultiQOSMeasurement, reinterpret_cast(this)); - fRTCPInstance->setByeHandler((TaskFunc*)MultiByeHandler, reinterpret_cast(this)); - + if(fRTCPInstance) + { + g_multiSession = this; + fRTCPInstance->setRRHandler((TaskFunc*)MultiQOSMeasurement, reinterpret_cast(this)); + fRTCPInstance->setByeHandler((TaskFunc*)MultiByeHandler, reinterpret_cast(this)); + } } diff --git a/pambase/iomanager.cpp b/pambase/iomanager.cpp index e6b2dbca..2fdc2a8f 100644 --- a/pambase/iomanager.cpp +++ b/pambase/iomanager.cpp @@ -77,9 +77,9 @@ IOManager::IOManager() : m_bPlaybackInput(false), m_bMonitorOutput(false), m_pGenerator(nullptr), - m_bStreamMulticast(false), - m_pMulticastServer(nullptr), - m_pUnicastServer(nullptr), + m_bStreamAlwaysOn(false), + m_pAlwaysOnServer(nullptr), + m_pOnDemandServer(nullptr), m_pOnDemandSubsession(nullptr), m_pSapServer(nullptr), m_pPublisher(nullptr), @@ -127,6 +127,7 @@ IOManager::IOManager() : Settings::Get().AddHandler(wxT("Server"), wxT("Stream"), this); Settings::Get().AddHandler(wxT("Server"), wxT("SAP"), this); Settings::Get().AddHandler(wxT("Server"), wxT("DNS-SD"), this); + Settings::Get().AddHandler(wxT("Server"), wxT("State"), this); Connect(wxID_ANY,wxEVT_DATA,(wxObjectEventFunction)&IOManager::OnAudioEvent); Connect(wxID_ANY,wxEVT_RTP_SESSION,(wxObjectEventFunction)&IOManager::OnRTPSession); @@ -183,20 +184,20 @@ void IOManager::Stop() void IOManager::StopStream() { - if(m_pMulticastServer) + if(m_pAlwaysOnServer) { - m_pMulticastServer->StopStream(); - m_pMulticastServer->Wait(); - delete m_pMulticastServer; - m_pMulticastServer = nullptr; + m_pAlwaysOnServer->StopStream(); + m_pAlwaysOnServer->Wait(); + delete m_pAlwaysOnServer; + m_pAlwaysOnServer = nullptr; RTPServerFinished(); } - else if(m_pUnicastServer) + else if(m_pOnDemandServer) { - m_pUnicastServer->Stop(); - m_pUnicastServer->Wait(); - delete m_pUnicastServer; - m_pUnicastServer = nullptr; + m_pOnDemandServer->Stop(); + m_pOnDemandServer->Wait(); + delete m_pOnDemandServer; + m_pOnDemandServer = nullptr; m_pOnDemandSubsession = nullptr; RTPServerFinished(); } @@ -264,32 +265,43 @@ void IOManager::OnSettingEvent(SettingEvent& event) { if(event.GetKey() == wxT("Stream")) { - m_bStreamMulticast = (event.GetValue() == "Multicast"); - if(!m_bStreamMulticast) + m_bStreamAlwaysOn = (event.GetValue() == "AlwaysOn"); + if(!m_bStreamAlwaysOn) { - if(m_pMulticastServer) + if(m_pAlwaysOnServer) { - m_pMulticastServer->StopStream(); - m_pMulticastServer->Wait(); - delete m_pMulticastServer; - m_pMulticastServer = nullptr; + m_pAlwaysOnServer->StopStream(); + m_pAlwaysOnServer->Wait(); + delete m_pAlwaysOnServer; + m_pAlwaysOnServer = nullptr; RTPServerFinished(); } } else { - if(m_pUnicastServer) + if(m_pOnDemandServer) { - m_pUnicastServer->Stop(); - m_pUnicastServer->Wait(); - delete m_pUnicastServer; - m_pUnicastServer = nullptr; + m_pOnDemandServer->Stop(); + m_pOnDemandServer->Wait(); + delete m_pOnDemandServer; + m_pOnDemandServer = nullptr; m_pOnDemandSubsession = nullptr; RTPServerFinished(); } } InitAudioOutputDevice(); } + else if(event.GetKey() == "State") + { + if(event.GetValue(false)) + { + InitAudioOutputDevice(); + } + else + { + StopStream(); + } + } else if(event.GetKey() == wxT("SAP")) { DoSAP(event.GetValue(false)); @@ -312,9 +324,9 @@ void IOManager::OnAudioEvent(AudioEvent& event) SoundcardManager::Get().AddOutputSamples(event.GetBuffer()); break; case AudioEvent::RTP: - if(m_pMulticastServer) + if(m_pAlwaysOnServer) { - m_pMulticastServer->AddSamples(event.GetBuffer()); + m_pAlwaysOnServer->AddSamples(event.GetBuffer()); } else if(m_pOnDemandSubsession) { @@ -365,9 +377,9 @@ void IOManager::AddOutputSamples(size_t nSize) SoundcardManager::Get().AddOutputSamples(pBuffer); break; case AudioEvent::RTP: - if(m_pMulticastServer) + if(m_pAlwaysOnServer) { - m_pMulticastServer->AddSamples(pBuffer); + m_pAlwaysOnServer->AddSamples(pBuffer); } else if(m_pOnDemandSubsession) { @@ -497,7 +509,6 @@ void IOManager::OutputDestinationChanged() void IOManager::OutputChanged(const wxString& sKey) { - if(sKey == wxT("Destination")) { OutputDestinationChanged(); @@ -513,9 +524,9 @@ void IOManager::OutputChanged(const wxString& sKey) SoundcardManager::Get().FlushOutputQueue(); break; case AudioEvent::RTP: - if(m_pMulticastServer) + if(m_pAlwaysOnServer) { - m_pMulticastServer->FlushQueue(); + m_pAlwaysOnServer->FlushQueue(); } else if(m_pOnDemandSubsession) { @@ -770,29 +781,9 @@ void IOManager::InitAudioInputDevice(bool bStart) CheckPlayback(SoundcardManager::Get().GetInputSampleRate(), SoundcardManager::Get().GetInputNumberOfChannels()); } - else if(sType == "AoIP" || sType == "AoIP Manual" || (sType == "NMOS" && !bStart)) + else if(sType == "AoIP" || (sType == "AoIP Manual") || (sType == "NMOS" && !bStart)) { - m_nInputSource = AudioEvent::RTP; - pmlLog(pml::LOG_INFO) << "IOManager\tCreate Audio Input Device: AoIP"; - - AoIPSource source(0); - source = AoipSourceManager::Get().FindSource(Settings::Get().Read(wxT("Input"), wxT("AoIP"), 0)); - - if(source.nIndex != 0 && m_mRtp.find(source.nIndex) == m_mRtp.end()) - { - m_nCurrentRtp = source.nIndex; - RtpThread* pThread = new RtpThread(this, Settings::Get().Read(wxT("AoIP_Settings"), wxT("Interface"), "eth0"), wxT("pam"), source, 2048); - pThread->Create(); - pThread->Run(); - - pThread->SetQosMeasurementIntervalMS(Settings::Get().Read(wxT("QoS"), wxT("Interval"), 1000)); - - m_mRtp.insert(make_pair(m_nCurrentRtp, pThread)); - } - else - { - pmlLog(pml::LOG_WARN) << "IOManager\tRTP Thread already running for source " << source.nIndex; - } + InitAoIPInput(); } else if(sType == wxT("Output")) { @@ -808,6 +799,30 @@ void IOManager::InitAudioInputDevice(bool bStart) } } +void IOManager::InitAoIPInput() +{ + m_nInputSource = AudioEvent::RTP; + pmlLog(pml::LOG_INFO) << "IOManager\tCreate Audio Input Device: AoIP"; + + AoIPSource source(0); + source = AoipSourceManager::Get().FindSource(Settings::Get().Read(wxT("Input"), wxT("AoIP"), 0)); + + if(source.nIndex != 0 && m_mRtp.find(source.nIndex) == m_mRtp.end()) + { + m_nCurrentRtp = source.nIndex; + RtpThread* pThread = new RtpThread(this, Settings::Get().Read(wxT("AoIP_Settings"), wxT("Interface"), "eth0"), wxT("pam"), source, 2048); + pThread->Create(); + pThread->Run(); + + pThread->SetQosMeasurementIntervalMS(Settings::Get().Read(wxT("QoS"), wxT("Interval"), 1000)); + + m_mRtp.insert(make_pair(m_nCurrentRtp, pThread)); + } + else + { + pmlLog(pml::LOG_WARN) << "IOManager\tRTP Thread already running for source " << source.nIndex; + } +} void IOManager::InitAudioOutputDevice() @@ -820,7 +835,7 @@ void IOManager::InitAudioOutputDevice() OpenSoundcardDevice(SoundcardManager::Get().GetOutputSampleRate()); m_nOutputDestination = AudioEvent::SOUNDCARD; - + //turn off any advertising of stream DoSAP(false); @@ -899,7 +914,7 @@ void IOManager::UpdateOutputSession() if(m_SessionOut.lstSubsession.back().nSampleRate != nSampleRate || m_SessionOut.lstSubsession.back().nChannels != nChannels) { m_SessionOut.lstSubsession.back().nSampleRate = nSampleRate; - m_SessionOut.lstSubsession.back().nChannels = nChannels; + m_SessionOut.lstSubsession.back().nChannels = nChannels; SessionChanged(); } } @@ -1073,7 +1088,7 @@ void IOManager::OnPtpEvent(wxCommandEvent& event) void IOManager::DoSAP(bool bRun) { - if(bRun == false || m_pMulticastServer == nullptr) + if(bRun == false || m_pAlwaysOnServer == nullptr) { if(m_pSapServer) { @@ -1094,15 +1109,15 @@ void IOManager::DoSAP(bool bRun) } - m_pSapServer->AddSender(IpAddress(std::string(Settings::Get().Read(wxT("Server"), wxT("RTSP_Address"), wxEmptyString).c_str())), std::chrono::milliseconds(30000), m_pMulticastServer->GetSDP()); + m_pSapServer->AddSender(IpAddress(std::string(Settings::Get().Read(wxT("Server"), wxT("RTSP_Address"), wxEmptyString).c_str())), std::chrono::milliseconds(30000), m_pAlwaysOnServer->GetSDP()); - pmlLog(pml::LOG_INFO) << "IOManager\tStart SAP advertising: " << m_pMulticastServer->GetSDP(); + pmlLog(pml::LOG_INFO) << "IOManager\tStart SAP advertising: " << m_pAlwaysOnServer->GetSDP(); } } void IOManager::DoDNSSD(bool bRun) { - if(bRun == false || (m_pUnicastServer == nullptr && m_pMulticastServer == nullptr)) + if(bRun == false || (m_pOnDemandServer == nullptr && m_pAlwaysOnServer == nullptr)) { if(m_pPublisher) { @@ -1140,64 +1155,68 @@ void IOManager::RTPServerFinished() void IOManager::Stream() { - if(m_bStreamMulticast || (Settings::Get().Read("NMOS", "Node", 0) == 2 || Settings::Get().Read("NMOS", "Node", 0) == 3)) //@todo bodge for NMOS - { - StreamMulticast(); - DoSAP(Settings::Get().Read("Server", "SAP",0)); - } - else + bool bNmos = (Settings::Get().Read("NMOS", "Node", 0) == 2 || Settings::Get().Read("NMOS", "Node", 0) == 3); + + if(Settings::Get().Read("Server", "State", 0) == 1 || bNmos) //set to stream { - StreamUnicast(); - DoSAP(false); + if(m_bStreamAlwaysOn || bNmos) //@todo bodge for NMOS + { + StreamAlwaysOn(); + DoSAP(Settings::Get().Read("Server", "SAP",0)); + } + else + { + StreamOnDemand(); + DoSAP(false); + } + DoDNSSD(Settings::Get().Read("Server", "DNS-SD", 0)); } - - DoDNSSD(Settings::Get().Read("Server", "DNS-SD", 0)); } -void IOManager::StreamMulticast() +void IOManager::StreamAlwaysOn() { - pmlLog(pml::LOG_INFO) << "IOManager\tCreate Multicast AES67 Server"; - if(m_pMulticastServer == nullptr && m_pUnicastServer == nullptr) + pmlLog(pml::LOG_INFO) << "IOManager\tCreate AlwaysOn AES67 Server"; + if(m_pAlwaysOnServer == nullptr && m_pOnDemandServer == nullptr) { wxString sDestinationIp = Settings::Get().Read(wxT("Server"), wxT("DestinationIp"), wxEmptyString); unsigned long nByte; bool bSSM(sDestinationIp.BeforeFirst(wxT('.')).ToULong(&nByte) && nByte >= 224 && nByte <= 239); - m_pMulticastServer = new RtpServerThread(this, m_setRTCPHandlers, Settings::Get().Read(wxT("Server"), wxT("RTSP_Address"), wxEmptyString), + m_pAlwaysOnServer = new RtpServerThread(this, m_setRTCPHandlers, Settings::Get().Read(wxT("Server"), wxT("RTSP_Address"), wxEmptyString), Settings::Get().Read(wxT("Server"), wxT("RTSP_Port"), 5555), sDestinationIp, Settings::Get().Read(wxT("Server"), wxT("RTP_Port"), 5004), bSSM, (LiveAudioSource::enumPacketTime)Settings::Get().Read(wxT("Server"), wxT("PacketTime"), 1000)); - m_pMulticastServer->Run(); + m_pAlwaysOnServer->Run(); m_bStreamActive = true; } else { - pmlLog(pml::LOG_ERROR) << "Attempting to stream multicast but already streaming"; + pmlLog(pml::LOG_ERROR) << "Attempting to stream AlwaysOn but already streaming"; } } -void IOManager::StreamUnicast() +void IOManager::StreamOnDemand() { - pmlLog(pml::LOG_INFO) << "IOManager\tCreate Unicast AES67 Server"; - if(m_pMulticastServer == nullptr && m_pUnicastServer == nullptr) + pmlLog(pml::LOG_INFO) << "IOManager\tCreate OnDemand AES67 Server"; + if(m_pAlwaysOnServer == nullptr && m_pOnDemandServer == nullptr) { - m_pUnicastServer = new OnDemandStreamer(m_setRTSPHandlers, m_setRTCPHandlers, Settings::Get().Read(wxT("Server"), wxT("RTSP_Address"), "0.0.0.0"), + m_pOnDemandServer = new OnDemandStreamer(m_setRTSPHandlers, m_setRTCPHandlers, Settings::Get().Read(wxT("Server"), wxT("RTSP_Address"), "0.0.0.0"), Settings::Get().Read(wxT("Server"), wxT("RTSP_Port"), 5555)); - m_pOnDemandSubsession = OnDemandAES67MediaSubsession::createNew(this, *m_pUnicastServer->envir(), 2, (LiveAudioSource::enumPacketTime)Settings::Get().Read(wxT("Server"), wxT("PacketTime"), 1000), Settings::Get().Read(wxT("Server"), wxT("RTP_Port"), 5004)); + m_pOnDemandSubsession = OnDemandAES67MediaSubsession::createNew(this, *m_pOnDemandServer->envir(), 2, (LiveAudioSource::enumPacketTime)Settings::Get().Read(wxT("Server"), wxT("PacketTime"), 1000), Settings::Get().Read(wxT("Server"), wxT("RTP_Port"), 5004)); - m_pUnicastServer->Create(); - m_pUnicastServer->SetSubsession(m_pOnDemandSubsession); + m_pOnDemandServer->Create(); + m_pOnDemandServer->SetSubsession(m_pOnDemandSubsession); - m_pUnicastServer->Run(); + m_pOnDemandServer->Run(); m_bStreamActive = true; } else { - pmlLog(pml::LOG_ERROR) << "Attempting to stream unicast but already streaming"; + pmlLog(pml::LOG_ERROR) << "Attempting to stream OnDemand but already streaming"; } } @@ -1229,6 +1248,6 @@ void IOManager::OnTimerReset(wxTimerEvent& event) wxString IOManager::GetDnsSdService() const { - return "AES67@"+wxGetHostName(); + return "AES67@"+wxGetHostName(); } diff --git a/pambase/iomanager.h b/pambase/iomanager.h index 5be844c4..d85d0d17 100644 --- a/pambase/iomanager.h +++ b/pambase/iomanager.h @@ -102,12 +102,13 @@ class PAMBASE_IMPEXPORT IOManager : public wxEvtHandler void RTPServerFinished(); void Stream(); - void StreamMulticast(); - void StreamUnicast(); + void StreamAlwaysOn(); + void StreamOnDemand(); void StopStream(); void DoGain(AudioEvent& event); void CheckIfGain(); + void InitAoIPInput(); std::set m_setHandlers; std::set m_setRTCPHandlers; @@ -122,15 +123,15 @@ class PAMBASE_IMPEXPORT IOManager : public wxEvtHandler int m_nPlaybackSource; bool m_bPlaybackInput; bool m_bMonitorOutput; - bool m_bStreamMulticast; + bool m_bStreamAlwaysOn; Generator* m_pGenerator; std::map m_mRtp; std::set m_setRtpOrphan; int m_nCurrentRtp; - RtpServerThread* m_pMulticastServer; - OnDemandStreamer* m_pUnicastServer; + RtpServerThread* m_pAlwaysOnServer; + OnDemandStreamer* m_pOnDemandServer; OnDemandAES67MediaSubsession* m_pOnDemandSubsession; wxTimer m_timerSilence; wxTimer m_timerResetStream; diff --git a/pambase/rtpserverthread.cpp b/pambase/rtpserverthread.cpp index 71b8cf72..6e0f76da 100644 --- a/pambase/rtpserverthread.cpp +++ b/pambase/rtpserverthread.cpp @@ -27,7 +27,7 @@ RtpServerThread::RtpServerThread(wxEvtHandler* pHandler, const std::setmulticastSendOnly(); // we're a SSM source - m_pRtcpGroupsock->multicastSendOnly(); // we're a SSM source + if(m_bRTCP) + { + m_pRtcpGroupsock->multicastSendOnly(); // we're a SSM source + } } @@ -113,15 +120,18 @@ bool RtpServerThread::CreateStream() // Create and start a RTSP server to serve this stream: pmlLog() << "RTP Server: Create RTSP Server on port " << m_nRTSPPort; m_pRtspServer = PamRTSPServer::createNew(*m_penv, m_nRTSPPort); - // Create (and start) a 'RTCP instance' for this RTP sink: - const unsigned int nEstimatedSessionBandwidth =( (m_pSource->samplingFrequency()*m_pSource->numChannels() * 3) + 500)/1000; // in kbps; for RTCP b/w share - const unsigned int nMaxCNAMElen = 100; - unsigned char CNAME[nMaxCNAMElen+1]; - gethostname((char*)CNAME, nMaxCNAMElen); - CNAME[nMaxCNAMElen] = '\0'; // just in case - m_pRtcpInstance = RTCPInstance::createNew(*m_penv, m_pRtcpGroupsock, nEstimatedSessionBandwidth, CNAME, m_pSink, NULL, True); + // Create (and start) a 'RTCP instance' for this RTP sink: + if(m_bRTCP) + { + const unsigned int nEstimatedSessionBandwidth =( (m_pSource->samplingFrequency()*m_pSource->numChannels() * 3) + 500)/1000; // in kbps; for RTCP b/w share + const unsigned int nMaxCNAMElen = 100; + unsigned char CNAME[nMaxCNAMElen+1]; + gethostname((char*)CNAME, nMaxCNAMElen); + CNAME[nMaxCNAMElen] = '\0'; // just in case + m_pRtcpInstance = RTCPInstance::createNew(*m_penv, m_pRtcpGroupsock, nEstimatedSessionBandwidth, CNAME, m_pSink, NULL, True); + } bool bOk(true); @@ -130,7 +140,7 @@ bool RtpServerThread::CreateStream() pmlLog(pml::LOG_ERROR) << "RTP Server\tFailed to create RTSP server: " << m_penv->getResultMsg(); bOk = false; } - if(m_pRtcpInstance == nullptr) + if(m_pRtcpInstance == nullptr && m_bRTCP) { pmlLog(pml::LOG_ERROR) << "RTP Server\tFailed to create RTCP Instance: " << m_penv->getResultMsg(); bOk = false; @@ -145,13 +155,18 @@ bool RtpServerThread::CreateStream() m_bStreaming = false; delete m_pRtpGroupsock; m_pRtpGroupsock = nullptr; + if(m_pRtcpGroupsock) + { + delete m_pRtcpGroupsock; + } + m_pRtcpGroupsock = nullptr; return false; } wxString sStream = "by-name/"+ IOManager::Get().GetDnsSdService(); - ServerMediaSession* sms = ServerMediaSession::createNew(*m_penv, sStream, nullptr, "PAM_AES67", True/*SSM*/); + ServerMediaSession* sms = ServerMediaSession::createNew(*m_penv, sStream, nullptr, "PAM AES67", m_bSSM); AES67ServerMediaSubsession* pSmss = AES67ServerMediaSubsession::createNew(m_setRTCPHandlers, *m_pSink, m_pRtcpInstance, m_ePacketTime); sms->addSubsession(pSmss); m_pRtspServer->addServerMediaSession(sms); @@ -190,8 +205,11 @@ void RtpServerThread::CloseStream() Medium::close(m_pSink); delete m_pRtpGroupsock; Medium::close(m_pSource); - Medium::close(m_pRtcpInstance); - delete m_pRtcpGroupsock; + if(m_pRtcpInstance) + { + Medium::close(m_pRtcpInstance); + delete m_pRtcpGroupsock; + } m_pSource = nullptr; m_pSink = nullptr; m_pRtpGroupsock = nullptr; diff --git a/pambase/rtpserverthread.h b/pambase/rtpserverthread.h index c3ddf8f7..9dc7f690 100644 --- a/pambase/rtpserverthread.h +++ b/pambase/rtpserverthread.h @@ -58,5 +58,6 @@ class PAMBASE_IMPEXPORT RtpServerThread : public wxThread PamRTSPServer* m_pRtspServer; std::string m_sSDP; bool m_bStreaming; + bool m_bRTCP; }; diff --git a/pambase/settings.cpp b/pambase/settings.cpp index f508b785..8f2bee9c 100644 --- a/pambase/settings.cpp +++ b/pambase/settings.cpp @@ -7,6 +7,7 @@ #include "pmcontrol.h" #include "pmpanel.h" #include "pam2_paths.h" + #ifdef __WXMSW__ #include #include diff --git a/pambase/wmbutton.cpp b/pambase/wmbutton.cpp index e777e4d5..af5e5531 100644 --- a/pambase/wmbutton.cpp +++ b/pambase/wmbutton.cpp @@ -490,7 +490,7 @@ void wmButton::DrawToggle(wxDC& dc) m_uiRect.SetBackgroundColour(m_clrBackground[STATE_NORMAL]); m_uiRect.SetForegroundColour(m_clrForeground[STATE_NORMAL]); - + m_uiRect.SetTop(m_uiGroove.GetTop()+2); m_uiRect.SetBottom(m_uiGroove.GetBottom()-2); diff --git a/pambase/wmipeditpnl.cpp b/pambase/wmipeditpnl.cpp index 1994a4f9..1d0c68f2 100644 --- a/pambase/wmipeditpnl.cpp +++ b/pambase/wmipeditpnl.cpp @@ -18,10 +18,13 @@ BEGIN_EVENT_TABLE(wmipeditpnl,pmPanel) //*) END_EVENT_TABLE() +wxDEFINE_EVENT(wxEVT_IPEDIT_CHANGE, wxCommandEvent); + #ifdef WXSPAM IMPLEMENT_DYNAMIC_CLASS(wmipeditpnl, pmControl) #else wxIMPLEMENT_DYNAMIC_CLASS(wmipeditpnl, pmPanel); + #endif // WXSPAM wmipeditpnl::wmipeditpnl() : pmPanel(), @@ -150,6 +153,10 @@ void wmipeditpnl::CheckEdit(wmEdit* pCurrent, wmEdit* pNext) pNext->SetInsertPos(0); } } + + wxCommandEvent event(wxEVT_IPEDIT_CHANGE, GetId()); + event.SetString(GetValue()); + wxPostEvent(GetParent(), event); } void wmipeditpnl::OnSetFocus(wxFocusEvent& event) diff --git a/pambase/wmipeditpnl.h b/pambase/wmipeditpnl.h index 0103a92e..136a7cd5 100644 --- a/pambase/wmipeditpnl.h +++ b/pambase/wmipeditpnl.h @@ -71,5 +71,5 @@ class PAMBASE_IMPEXPORT wmipeditpnl: public pmPanel DECLARE_EVENT_TABLE() }; - +wxDECLARE_EXPORTED_EVENT(WXEXPORT, wxEVT_IPEDIT_CHANGE, wxCommandEvent); #endif