tcpConnection.cpp (5553B)
1 #include "tcpConnection.h" 2 3 #include "audioBuffers.h" 4 #include "networkLib/exception.h" 5 #include "networkLib/logging.h" 6 7 #include "synthLib/midiTypes.h" 8 9 namespace bridgeLib 10 { 11 TcpConnection::TcpConnection(std::unique_ptr<networkLib::TcpStream>&& _stream) : CommandReader(nullptr), m_stream(std::move(_stream)) 12 { 13 m_audioTransferBuffer.reserve(16384); 14 15 start(); 16 } 17 18 TcpConnection::~TcpConnection() 19 { 20 shutdown(); 21 } 22 23 void TcpConnection::handleCommand(const Command _command, baseLib::BinaryStream& _in) 24 { 25 switch (_command) 26 { 27 case Command::Invalid: 28 case Command::Ping: 29 case Command::Pong: 30 break; 31 case Command::PluginInfo: handleStruct<PluginDesc>(_in); break; 32 case Command::ServerInfo: handleStruct<ServerInfo>(_in); break; 33 case Command::Error: handleStruct<Error>(_in); break; 34 case Command::DeviceInfo: handleDeviceInfo(_in); break; 35 case Command::Midi: handleMidi(_in); break; 36 case Command::Audio: handleAudio(_in); break; 37 case Command::DeviceState: handleDeviceState(_in); break; 38 case Command::RequestDeviceState: handleRequestDeviceState(_in); break; 39 case Command::DeviceCreateParams: handleStruct<DeviceCreateParams>(_in); break; 40 case Command::SetSamplerate: handleStruct<SetSamplerate>(_in); break; 41 case Command::SetDspClockPercent: handleStruct<SetDspClockPercent>(_in); break; 42 case Command::SetUnknownCustomData: handleStruct<SetUnknownCustomData>(_in); break; 43 } 44 } 45 46 void TcpConnection::threadFunc() 47 { 48 try 49 { 50 NetworkThread::threadFunc(); 51 } 52 catch (const networkLib::NetException& e) 53 { 54 m_stream->close(); 55 LOGNET(networkLib::LogLevel::Warning, "Network Exception, code " << e.type() << ": " << e.what()); 56 handleException(e); 57 } 58 } 59 60 void TcpConnection::threadLoopFunc() 61 { 62 read(*m_stream); 63 } 64 65 void TcpConnection::send(const Command _command, const CommandStruct& _data) 66 { 67 m_writer.build(_command, _data); 68 m_writer.write(*m_stream); 69 } 70 71 void TcpConnection::send(Command _command) 72 { 73 m_writer.build(_command); 74 m_writer.write(*m_stream); 75 } 76 77 void TcpConnection::handleMidi(baseLib::BinaryStream& _in) 78 { 79 synthLib::SMidiEvent& ev = m_midiEvent; 80 _in.read(ev.a); 81 _in.read(ev.b); 82 _in.read(ev.c); 83 _in.read(ev.sysex); 84 _in.read(ev.offset); 85 ev.source = static_cast<synthLib::MidiEventSource>(_in.read<uint8_t>()); 86 handleMidi(ev); 87 } 88 89 void TcpConnection::sendAudio(const float* const* _data, const uint32_t _numChannels, const uint32_t _numSamplesPerChannel) 90 { 91 auto& s = m_writer.build(Command::Audio); 92 s.write(static_cast<uint8_t>(_numChannels)); 93 s.write(_numSamplesPerChannel); 94 95 for(uint32_t i=0; i<_numChannels; ++i) 96 { 97 // if a channel has data, write it. If not, write 0 for the length 98 if(const float* channelData = _data[i]) 99 { 100 s.write(_numSamplesPerChannel); 101 s.write(channelData, _numSamplesPerChannel); 102 } 103 else 104 { 105 s.write(0); 106 } 107 } 108 send(); 109 } 110 111 void TcpConnection::sendAudio(AudioBuffers& _buffers, const uint32_t _numChannels, uint32_t _numSamplesPerChannel) 112 { 113 auto& s = m_writer.build(Command::Audio); 114 s.write(static_cast<uint8_t>(_numChannels)); 115 s.write(_numSamplesPerChannel); 116 117 if(m_audioTransferBuffer.size() < _numSamplesPerChannel) 118 m_audioTransferBuffer.resize(_numSamplesPerChannel); 119 120 for(uint32_t i=0; i<_numChannels; ++i) 121 { 122 _buffers.readInput(i, m_audioTransferBuffer, _numSamplesPerChannel); 123 s.write(_numSamplesPerChannel); 124 s.write(m_audioTransferBuffer.data(), _numSamplesPerChannel); 125 } 126 127 _buffers.onInputRead(_numSamplesPerChannel); 128 129 send(); 130 } 131 132 uint32_t TcpConnection::handleAudio(float* const* _output, baseLib::BinaryStream& _in) 133 { 134 const uint32_t numChannels = _in.read<uint8_t>(); 135 const uint32_t numSamplesMax = _in.read<uint32_t>(); 136 137 for(uint32_t i=0; i<numChannels; ++i) 138 { 139 const auto numSamples = _in.read<uint32_t>(); 140 if(numSamples) 141 { 142 assert(_output[i]); 143 _in.read(_output[i], numSamples); 144 } 145 } 146 return numSamplesMax; 147 } 148 149 void TcpConnection::handleAudio(AudioBuffers& _buffers, baseLib::BinaryStream& _in) 150 { 151 const uint32_t numChannels = _in.read<uint8_t>(); 152 const uint32_t numSamplesMax = _in.read<uint32_t>(); 153 154 for(uint32_t i=0; i<numChannels; ++i) 155 { 156 const auto numSamples = _in.read<uint32_t>(); 157 158 if(numSamples) 159 { 160 if(m_audioTransferBuffer.size() < numSamples) 161 m_audioTransferBuffer.resize(numSamples); 162 _in.read(m_audioTransferBuffer.data(), numSamples); 163 _buffers.writeOutput(i, m_audioTransferBuffer, numSamples); 164 } 165 } 166 _buffers.onOutputWritten(numSamplesMax); 167 } 168 169 void TcpConnection::handleAudio(baseLib::BinaryStream& _in) 170 { 171 } 172 173 void TcpConnection::handleRequestDeviceState(baseLib::BinaryStream& _in) 174 { 175 RequestDeviceState requestDeviceState; 176 requestDeviceState.read(_in); 177 handleRequestDeviceState(requestDeviceState); 178 } 179 180 void TcpConnection::handleDeviceState(baseLib::BinaryStream& _in) 181 { 182 m_deviceState.read(_in); 183 handleDeviceState(m_deviceState); 184 } 185 186 void TcpConnection::handleDeviceInfo(baseLib::BinaryStream& _in) 187 { 188 handleStruct<DeviceDesc>(_in); 189 } 190 191 bool TcpConnection::send(const synthLib::SMidiEvent& _ev) 192 { 193 if(!isValid()) 194 return false; 195 auto& bs = m_writer.build(Command::Midi); 196 bs.write(_ev.a); 197 bs.write(_ev.b); 198 bs.write(_ev.c); 199 bs.write(_ev.sysex); 200 bs.write(_ev.offset); 201 bs.write<uint8_t>(static_cast<uint8_t>(_ev.source)); 202 send(); 203 return true; 204 } 205 206 void TcpConnection::close() const 207 { 208 if(m_stream) 209 m_stream->close(); 210 } 211 212 void TcpConnection::shutdown() 213 { 214 close(); 215 stop(); 216 m_stream.reset(); 217 } 218 }