JackTrip
|
00001 //***************************************************************** 00002 /* 00003 JackTrip: A System for High-Quality Audio Network Performance 00004 over the Internet 00005 00006 Copyright (c) 2008 Juan-Pablo Caceres, Chris Chafe. 00007 SoundWIRE group at CCRMA, Stanford University. 00008 00009 Permission is hereby granted, free of charge, to any person 00010 obtaining a copy of this software and associated documentation 00011 files (the "Software"), to deal in the Software without 00012 restriction, including without limitation the rights to use, 00013 copy, modify, merge, publish, distribute, sublicense, and/or sell 00014 copies of the Software, and to permit persons to whom the 00015 Software is furnished to do so, subject to the following 00016 conditions: 00017 00018 The above copyright notice and this permission notice shall be 00019 included in all copies or substantial portions of the Software. 00020 00021 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00022 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 00023 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00024 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 00025 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 00026 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00027 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00028 OTHER DEALINGS IN THE SOFTWARE. 00029 */ 00030 //***************************************************************** 00031 00038 #ifndef __JACKTRIP_H__ 00039 #define __JACKTRIP_H__ 00040 00041 #include <tr1/memory> //for shared_ptr 00042 00043 #include <QObject> 00044 #include <QString> 00045 00046 #include "DataProtocol.h" 00047 #include "JackAudioInterface.h" 00048 #include "PacketHeader.h" 00049 #include "RingBuffer.h" 00050 00051 00059 class JackTrip : public QThread 00060 { 00061 Q_OBJECT; 00062 00063 public: 00064 00065 //----------ENUMS------------------------------------------ 00067 enum dataProtocolT { 00068 UDP, 00069 TCP, 00070 SCTP 00071 }; 00072 00074 enum jacktripModeT { 00075 SERVER, 00076 CLIENT, 00077 CLIENTTOPINGSERVER 00078 }; 00079 00081 enum underrunModeT { 00082 WAVETABLE, 00083 ZEROS 00084 }; 00085 //--------------------------------------------------------- 00086 00087 00096 JackTrip(jacktripModeT JacktripMode = CLIENT, 00097 dataProtocolT DataProtocolType = UDP, 00098 int NumChans = 2, 00099 int BufferQueueLength = 8, 00100 unsigned int redundancy = 1, 00101 JackAudioInterface::audioBitResolutionT AudioBitResolution = 00102 JackAudioInterface::BIT16, 00103 DataProtocol::packetHeaderTypeT PacketHeaderType = 00104 DataProtocol::DEFAULT, 00105 underrunModeT UnderRunMode = WAVETABLE, 00106 int receiver_bind_port = gDefaultPort, 00107 int sender_bind_port = gDefaultPort, 00108 int receiver_peer_port = gDefaultPort, 00109 int sender_peer_port = gDefaultPort); 00110 00112 virtual ~JackTrip(); 00113 00115 void setPeerAddress(const char* PeerHostOrIP); 00116 00120 //void appendProcessPlugin(const std::tr1::shared_ptr<ProcessPlugin> plugin); 00121 void appendProcessPlugin(ProcessPlugin* plugin); 00122 00124 void start(); 00125 00127 void stop(); 00128 00131 void wait(); 00132 00135 void checkIfPortIsBinded(int port); 00136 00137 //------------------------------------------------------------------------------------ 00139 00140 // 00142 void setJackTripMode(jacktripModeT JacktripMode) 00143 { mJackTripMode = JacktripMode; } 00145 void setDataProtocoType(dataProtocolT DataProtocolType) 00146 { mDataProtocol = DataProtocolType; } 00148 void setPacketHeaderType(DataProtocol::packetHeaderTypeT PacketHeaderType) 00149 { 00150 mPacketHeaderType = PacketHeaderType; 00151 delete mPacketHeader; 00152 mPacketHeader = NULL; 00153 createHeader(mPacketHeaderType); 00154 } 00157 //void setNumChannels(int NumChans) 00158 //{ mNumChans=NumChans; } 00160 void setBufferQueueLength(int BufferQueueLength) 00161 { mBufferQueueLength = BufferQueueLength; } 00163 void setAudioBitResolution(JackAudioInterface::audioBitResolutionT AudioBitResolution) 00164 { mAudioBitResolution = AudioBitResolution; } 00166 void setUnderRunMode(underrunModeT UnderRunMode) 00167 { mUnderRunMode = UnderRunMode; } 00170 void setAllPorts(int port) 00171 { 00172 mReceiverBindPort = port; 00173 mSenderPeerPort = port; 00174 mSenderBindPort = port; 00175 mReceiverPeerPort = port; 00176 } 00178 void setBindPorts(int port) 00179 { 00180 mReceiverBindPort = port; 00181 mSenderBindPort = port; 00182 } 00184 void setPeerPorts(int port) 00185 { 00186 mSenderPeerPort = port; 00187 mReceiverPeerPort = port; 00188 } 00190 void setClientName(char* ClientName) 00191 { mJackClientName = ClientName; } 00193 //------------------------------------------------------------------------------------ 00194 00195 00196 //------------------------------------------------------------------------------------ 00198 00199 00200 void createHeader(const DataProtocol::packetHeaderTypeT headertype); 00201 void putHeaderInPacket(int8_t* full_packet, int8_t* audio_packet); 00202 int getPacketSizeInBytes() const; 00203 void parseAudioPacket(int8_t* full_packet, int8_t* audio_packet); 00204 void sendNetworkPacket(const int8_t* ptrToSlot) 00205 { mSendRingBuffer->insertSlotNonBlocking(ptrToSlot); } 00206 void receiveNetworkPacket(int8_t* ptrToReadSlot) 00207 { mReceiveRingBuffer->readSlotNonBlocking(ptrToReadSlot); } 00208 void readAudioBuffer(int8_t* ptrToReadSlot) 00209 { mSendRingBuffer->readSlotBlocking(ptrToReadSlot); } 00210 void writeAudioBuffer(const int8_t* ptrToSlot) 00211 { mReceiveRingBuffer->insertSlotNonBlocking(ptrToSlot); } 00212 uint32_t getBufferSizeInSamples() const 00213 { return mJackAudio->getBufferSizeInSamples(); } 00214 JackAudioInterface::samplingRateT getSampleRateType() const 00215 { return mJackAudio->getSampleRateType(); } 00216 uint8_t getAudioBitResolution() const 00217 { return mJackAudio->getAudioBitResolution(); } 00218 int getNumInputChannels() const 00219 { return mJackAudio->getNumInputChannels(); } 00220 int getNumOutputChannels() const 00221 {return mJackAudio->getNumOutputChannels(); } 00222 void checkPeerSettings(int8_t* full_packet); 00223 void increaseSequenceNumber() 00224 { mPacketHeader->increaseSequenceNumber(); } 00225 int getSequenceNumber() const 00226 { return mPacketHeader->getSequenceNumber(); } 00227 int getPeerSequenceNumber(int8_t* full_packet) const 00228 { return mPacketHeader->getPeerSequenceNumber(full_packet); } 00230 //------------------------------------------------------------------------------------ 00231 00232 00233 public slots: 00235 void slotStopProcesses() 00236 { 00237 std::cout << "Stopping JackTrip..." << std::endl; 00238 stop(); 00239 }; 00240 00246 void slotUdpWatingTooLong(int wait_msec) 00247 { 00248 int wait_time = 30000; // msec 00249 if ( !(wait_msec%wait_time) ) { 00250 std::cerr << "UDP WAITED MORE THAN 30 seconds." << std::endl; 00251 emit signalNoUdpPacketsForSeconds(); 00252 } 00253 } 00254 00255 00256 signals: 00258 void signalProcessesStopped(); 00260 void signalNoUdpPacketsForSeconds(); 00261 00262 00263 private: 00264 00266 void setupJackAudio(); 00268 void setupDataProtocol(); 00270 void setupRingBuffers(); 00272 void clientStart(); 00274 void serverStart(); 00276 void clientPingToServerStart(); 00277 00278 jacktripModeT mJackTripMode; 00279 dataProtocolT mDataProtocol; 00280 DataProtocol::packetHeaderTypeT mPacketHeaderType; 00281 00282 int mNumChans; 00283 int mBufferQueueLength; 00284 uint32_t mSampleRate; 00285 uint32_t mAudioBufferSize; 00286 JackAudioInterface::audioBitResolutionT mAudioBitResolution; 00287 QString mPeerAddress; 00288 00290 DataProtocol* mDataProtocolSender; 00292 DataProtocol* mDataProtocolReceiver; 00293 JackAudioInterface* mJackAudio; 00294 PacketHeader* mPacketHeader; 00295 underrunModeT mUnderRunMode; 00296 00298 RingBuffer* mSendRingBuffer; 00300 RingBuffer* mReceiveRingBuffer; 00301 00302 int mReceiverBindPort; 00303 int mSenderPeerPort; 00304 int mSenderBindPort; 00305 int mReceiverPeerPort; 00306 00307 unsigned int mRedundancy; 00308 const char* mJackClientName; 00309 00310 QVector<ProcessPlugin*> mProcessPlugins; 00311 }; 00312 00313 #endif