mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-03 13:11:20 -05:00 
			
		
		
		
	Added RTP Sink based on JRTPLib and AudioNetSink to handle sending audio over the network via UDP or RTP
This commit is contained in:
		
							parent
							
								
									f4e2ac61f8
								
							
						
					
					
						commit
						cc461f2f0f
					
				@ -57,9 +57,9 @@ find_package(Qt5Multimedia 5.0 REQUIRED)
 | 
			
		||||
#find_package(QT5OpenGL 5.0 REQUIRED)
 | 
			
		||||
find_package(OpenGL REQUIRED)
 | 
			
		||||
find_package(PkgConfig)
 | 
			
		||||
 | 
			
		||||
find_package(Boost REQUIRED)
 | 
			
		||||
find_package(FFTW3F)
 | 
			
		||||
find_package(JRTPLib)
 | 
			
		||||
 | 
			
		||||
if (NOT BUILD_DEBIAN)
 | 
			
		||||
    find_package(LibDSDcc)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								cmake/Modules/FindJRTPLib.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								cmake/Modules/FindJRTPLib.cmake
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
INCLUDE(FindPkgConfig)
 | 
			
		||||
PKG_CHECK_MODULES(PC_JRTPLIB "jrtplib")
 | 
			
		||||
 | 
			
		||||
FIND_PATH(JRTPLIB_INCLUDE_DIR
 | 
			
		||||
    NAMES rtpsession.h
 | 
			
		||||
    HINTS ${PC_JRTPLIB_INCLUDE_DIR}
 | 
			
		||||
    ${CMAKE_INSTALL_PREFIX}/include/jrtplib3
 | 
			
		||||
    ${JRTPLIB_INSTALL_PREFIX}/include/jrtplib3
 | 
			
		||||
    PATHS
 | 
			
		||||
    /usr/local/include/jrtplib3
 | 
			
		||||
    /usr/include/jrtplib3
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
FIND_LIBRARY(JRTPLIB_LIBRARIES
 | 
			
		||||
    NAMES libjrtp
 | 
			
		||||
    HINTS ${PC_JRTPLIB_LIBDIR}
 | 
			
		||||
    ${CMAKE_INSTALL_PREFIX}/lib
 | 
			
		||||
    ${CMAKE_INSTALL_PREFIX}/lib64
 | 
			
		||||
    PATHS
 | 
			
		||||
    ${JRTPLIB_INCLUDE_DIR}/../lib
 | 
			
		||||
    /usr/local/lib
 | 
			
		||||
    /usr/local/lib64
 | 
			
		||||
    /usr/lib
 | 
			
		||||
    /usr/lib64
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if(JRTPLIB_INCLUDE_DIR AND JRTPLIB_LIBRARIES)
 | 
			
		||||
    set(JRTPLIB_FOUND TRUE CACHE INTERNAL "JRTPLib found")
 | 
			
		||||
    message(STATUS "Found JRTPLib: ${JRTPLIB_INCLUDE_DIR}, ${JRTPLIB_LIBRARIES}")
 | 
			
		||||
else()
 | 
			
		||||
    set(JRTPLIB_FOUND FALSE CACHE INTERNAL "JRTPLib found")
 | 
			
		||||
    message(STATUS "JRTPLib not found")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
INCLUDE(FindPackageHandleStandardArgs)
 | 
			
		||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(JRTPLIB DEFAULT_MSG JRTPLIB_LIBRARIES JRTPLIB_INCLUDE_DIR)
 | 
			
		||||
MARK_AS_ADVANCED(JRTPLIB_LIBRARIES JRTPLIB_INCLUDE_DIR)
 | 
			
		||||
@ -7,7 +7,8 @@ set(sdrbase_SOURCES
 | 
			
		||||
    audio/audiofifo.cpp
 | 
			
		||||
    audio/audiooutput.cpp
 | 
			
		||||
    audio/audioinput.cpp
 | 
			
		||||
 | 
			
		||||
    audio/audionetsink.cpp
 | 
			
		||||
    
 | 
			
		||||
    channel/channelsinkapi.cpp
 | 
			
		||||
    channel/channelsourceapi.cpp
 | 
			
		||||
    commands/command.cpp
 | 
			
		||||
@ -85,6 +86,7 @@ set(sdrbase_HEADERS
 | 
			
		||||
    audio/audiofifo.h
 | 
			
		||||
    audio/audiooutput.h
 | 
			
		||||
    audio/audioinput.h
 | 
			
		||||
    audio/audionetsink.h
 | 
			
		||||
 | 
			
		||||
    channel/channelsinkapi.h
 | 
			
		||||
    channel/channelsourceapi.h
 | 
			
		||||
@ -209,6 +211,15 @@ else(FFTW3F_FOUND)
 | 
			
		||||
    add_definitions(-DUSE_KISSFFT)
 | 
			
		||||
endif(FFTW3F_FOUND)
 | 
			
		||||
 | 
			
		||||
if (JRTPLIB_FOUND)
 | 
			
		||||
    set(sdrbase_HEADERS
 | 
			
		||||
        ${sdrbase_HEADERS}
 | 
			
		||||
        util/rtpsink.h
 | 
			
		||||
    )
 | 
			
		||||
    add_definitions(-DHAS_JRTPLIB)
 | 
			
		||||
    include_directories(${JRTPLIB_INCLUDE_DIR})
 | 
			
		||||
endif(JRTPLIB_FOUND)
 | 
			
		||||
 | 
			
		||||
if (LIBSERIALDV_FOUND)
 | 
			
		||||
    set(sdrbase_SOURCES
 | 
			
		||||
        ${sdrbase_SOURCES}
 | 
			
		||||
@ -271,6 +282,10 @@ if(FFTW3F_FOUND)
 | 
			
		||||
    target_link_libraries(sdrbase ${FFTW3F_LIBRARIES})
 | 
			
		||||
endif(FFTW3F_FOUND)
 | 
			
		||||
 | 
			
		||||
if (JRTPLIB_FOUND)
 | 
			
		||||
    target_link_libraries(sdrbase ${JRTPLIB_LIBRARIES})
 | 
			
		||||
endif(JRTPLIB_FOUND)
 | 
			
		||||
 | 
			
		||||
if(LIBSERIALDV_FOUND)
 | 
			
		||||
    target_link_libraries(sdrbase ${LIBSERIALDV_LIBRARY})
 | 
			
		||||
endif(LIBSERIALDV_FOUND)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										160
									
								
								sdrbase/audio/audionetsink.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								sdrbase/audio/audionetsink.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,160 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2018 F4EXB                                                      //
 | 
			
		||||
// written by Edouard Griffiths                                                  //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#include "audionetsink.h"
 | 
			
		||||
 | 
			
		||||
const int AudioNetSink::m_udpBlockSize = 512;
 | 
			
		||||
 | 
			
		||||
AudioNetSink::AudioNetSink(QObject *parent, bool stereo) :
 | 
			
		||||
    m_type(SinkUDP),
 | 
			
		||||
    m_udpBufferAudioMono(0),
 | 
			
		||||
    m_udpBufferAudioStereo(0)
 | 
			
		||||
{
 | 
			
		||||
    if (stereo)
 | 
			
		||||
    {
 | 
			
		||||
        m_udpBufferAudioStereo = new UDPSink<AudioSample>(parent, m_udpBlockSize);
 | 
			
		||||
#ifdef HAS_JRTPLIB
 | 
			
		||||
        m_rtpBufferAudioStereo = new RTPSink<AudioSample>("127.0.0.1", 9999, 48000);
 | 
			
		||||
        m_rtpBufferAudioMono = 0;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        m_udpBufferAudioMono = new UDPSink<int16_t>(parent, m_udpBlockSize);
 | 
			
		||||
#ifdef HAS_JRTPLIB
 | 
			
		||||
        m_rtpBufferAudioMono = new RTPSink<int16_t>("127.0.0.1", 9999, 48000);
 | 
			
		||||
        m_rtpBufferAudioStereo = 0;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AudioNetSink::~AudioNetSink()
 | 
			
		||||
{
 | 
			
		||||
    if (m_udpBufferAudioMono) { delete m_udpBufferAudioMono; }
 | 
			
		||||
    if (m_udpBufferAudioStereo) { delete m_udpBufferAudioStereo; }
 | 
			
		||||
#ifdef HAS_JRTPLIB
 | 
			
		||||
    if (m_rtpBufferAudioMono) { delete m_rtpBufferAudioMono; }
 | 
			
		||||
    if (m_rtpBufferAudioStereo) { delete m_rtpBufferAudioStereo; }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AudioNetSink::selectType(SinkType type)
 | 
			
		||||
{
 | 
			
		||||
    if (type == SinkUDP)
 | 
			
		||||
    {
 | 
			
		||||
        m_type = SinkUDP;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else if (type == SinkRTP)
 | 
			
		||||
    {
 | 
			
		||||
#ifdef HAS_JRTPLIB
 | 
			
		||||
        m_type = SinkRTP;
 | 
			
		||||
        return true;
 | 
			
		||||
#else
 | 
			
		||||
        m_type = SinkUDP;
 | 
			
		||||
        return false;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AudioNetSink::setDestination(const QString& address, uint16_t port)
 | 
			
		||||
{
 | 
			
		||||
    if (m_udpBufferAudioMono) {
 | 
			
		||||
        m_udpBufferAudioMono->setDestination(address, port);
 | 
			
		||||
    }
 | 
			
		||||
    if (m_udpBufferAudioStereo) {
 | 
			
		||||
        m_udpBufferAudioStereo->setDestination(address, port);
 | 
			
		||||
    }
 | 
			
		||||
#ifdef HAS_JRTPLIB
 | 
			
		||||
    if (m_rtpBufferAudioMono) {
 | 
			
		||||
        m_rtpBufferAudioMono->setDestination(address, port);
 | 
			
		||||
    }
 | 
			
		||||
    if (m_rtpBufferAudioStereo) {
 | 
			
		||||
        m_rtpBufferAudioStereo->setDestination(address, port);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AudioNetSink::addDestination(const QString& address, uint16_t port)
 | 
			
		||||
{
 | 
			
		||||
#ifdef HAS_JRTPLIB
 | 
			
		||||
    if (m_rtpBufferAudioMono) {
 | 
			
		||||
        m_rtpBufferAudioMono->addDestination(address, port);
 | 
			
		||||
    }
 | 
			
		||||
    if (m_rtpBufferAudioStereo) {
 | 
			
		||||
        m_rtpBufferAudioStereo->addDestination(address, port);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AudioNetSink::deleteDestination(const QString& address, uint16_t port)
 | 
			
		||||
{
 | 
			
		||||
#ifdef HAS_JRTPLIB
 | 
			
		||||
    if (m_rtpBufferAudioMono) {
 | 
			
		||||
        m_rtpBufferAudioMono->deleteDestination(address, port);
 | 
			
		||||
    }
 | 
			
		||||
    if (m_rtpBufferAudioStereo) {
 | 
			
		||||
        m_rtpBufferAudioStereo->deleteDestination(address, port);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AudioNetSink::setSampleRate(int sampleRate)
 | 
			
		||||
{
 | 
			
		||||
#ifdef HAS_JRTPLIB
 | 
			
		||||
    if (m_rtpBufferAudioMono) {
 | 
			
		||||
        m_rtpBufferAudioMono->setSampleRate(sampleRate);
 | 
			
		||||
    }
 | 
			
		||||
    if (m_rtpBufferAudioStereo) {
 | 
			
		||||
        m_rtpBufferAudioStereo->setSampleRate(sampleRate);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AudioNetSink::write(qint16 sample)
 | 
			
		||||
{
 | 
			
		||||
    if (m_udpBufferAudioMono == 0) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (m_type == SinkUDP) {
 | 
			
		||||
        m_udpBufferAudioMono->write(sample);
 | 
			
		||||
    } else if (m_type == SinkRTP) {
 | 
			
		||||
#ifdef HAS_JRTPLIB
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AudioNetSink::write(const AudioSample& sample)
 | 
			
		||||
{
 | 
			
		||||
    if (m_udpBufferAudioStereo == 0) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (m_type == SinkUDP) {
 | 
			
		||||
        m_udpBufferAudioStereo->write(sample);
 | 
			
		||||
    } else if (m_type == SinkRTP) {
 | 
			
		||||
#ifdef HAS_JRTPLIB
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										65
									
								
								sdrbase/audio/audionetsink.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								sdrbase/audio/audionetsink.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,65 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2018 F4EXB                                                      //
 | 
			
		||||
// written by Edouard Griffiths                                                  //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#ifndef SDRBASE_AUDIO_AUDIONETSINK_H_
 | 
			
		||||
#define SDRBASE_AUDIO_AUDIONETSINK_H_
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include "dsp/dsptypes.h"
 | 
			
		||||
#include "util/export.h"
 | 
			
		||||
#include "util/udpsink.h"
 | 
			
		||||
#ifdef HAS_JRTPLIB
 | 
			
		||||
#include "util/rtpsink.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class SDRANGEL_API AudioNetSink {
 | 
			
		||||
public:
 | 
			
		||||
    typedef enum
 | 
			
		||||
    {
 | 
			
		||||
        SinkUDP,
 | 
			
		||||
        SinkRTP
 | 
			
		||||
    } SinkType;
 | 
			
		||||
 | 
			
		||||
    AudioNetSink(QObject *parent, bool stereo = false);
 | 
			
		||||
    ~AudioNetSink();
 | 
			
		||||
 | 
			
		||||
    void setDestination(const QString& address, uint16_t port);
 | 
			
		||||
    void addDestination(const QString& address, uint16_t port);
 | 
			
		||||
    void deleteDestination(const QString& address, uint16_t port);
 | 
			
		||||
    void setSampleRate(int sampleRate);
 | 
			
		||||
 | 
			
		||||
    void write(qint16 sample);
 | 
			
		||||
    void write(const AudioSample& sample);
 | 
			
		||||
 | 
			
		||||
    bool selectType(SinkType type);
 | 
			
		||||
 | 
			
		||||
    static const int m_udpBlockSize;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    SinkType m_type;
 | 
			
		||||
    UDPSink<qint16> *m_udpBufferAudioMono;
 | 
			
		||||
    UDPSink<AudioSample> *m_udpBufferAudioStereo;
 | 
			
		||||
#ifdef HAS_JRTPLIB
 | 
			
		||||
    RTPSink<qint16> *m_rtpBufferAudioMono;
 | 
			
		||||
    RTPSink<AudioSample> *m_rtpBufferAudioStereo;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* SDRBASE_AUDIO_AUDIONETSINK_H_ */
 | 
			
		||||
							
								
								
									
										143
									
								
								sdrbase/util/rtpsink.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								sdrbase/util/rtpsink.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,143 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Copyright (C) 2018 F4EXB                                                      //
 | 
			
		||||
// written by Edouard Griffiths                                                  //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is free software; you can redistribute it and/or modify          //
 | 
			
		||||
// it under the terms of the GNU General Public License as published by          //
 | 
			
		||||
// the Free Software Foundation as version 3 of the License, or                  //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// This program is distributed in the hope that it will be useful,               //
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
			
		||||
// GNU General Public License V3 for more details.                               //
 | 
			
		||||
//                                                                               //
 | 
			
		||||
// You should have received a copy of the GNU General Public License             //
 | 
			
		||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#ifndef SDRBASE_UTIL_RTPSINK_H_
 | 
			
		||||
#define SDRBASE_UTIL_RTPSINK_H_
 | 
			
		||||
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QMutex>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
// jrtplib includes
 | 
			
		||||
#include "rtpsession.h"
 | 
			
		||||
#include "rtpudpv4transmitter.h"
 | 
			
		||||
#include "rtpipv4address.h"
 | 
			
		||||
#include "rtpsessionparams.h"
 | 
			
		||||
#include "rtperrors.h"
 | 
			
		||||
#include "rtplibraryversion.h"
 | 
			
		||||
 | 
			
		||||
template<typename SampleType>
 | 
			
		||||
class RTPSink
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    RTPSink(const QString& address, uint16_t port, int sampleRate) :
 | 
			
		||||
        m_destport(port),
 | 
			
		||||
        m_sampleBuffer(0),
 | 
			
		||||
        m_sampleBufferIndex(0),
 | 
			
		||||
        m_mutex(QMutex::Recursive)
 | 
			
		||||
    {
 | 
			
		||||
        m_destip = inet_addr(address.toStdString().c_str());
 | 
			
		||||
        m_destip = ntohl(m_destip);
 | 
			
		||||
        m_rtpSessionParams.SetOwnTimestampUnit(1.0/(double) sampleRate);
 | 
			
		||||
        m_rtpTransmissionParams.SetPortbase(8092); // FIXME: sort this out
 | 
			
		||||
 | 
			
		||||
        int status = m_rtpSession.Create(m_rtpSessionParams, &m_rtpTransmissionParams);
 | 
			
		||||
 | 
			
		||||
        if (status < 0)
 | 
			
		||||
        {
 | 
			
		||||
            qCritical("RTPSink::RTPSink: cannot create session: %s", jrtplib::RTPGetErrorString(status).c_str());
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        status = m_rtpSession.AddDestination(jrtplib::RTPIPv4Address(m_destip, m_destport));
 | 
			
		||||
 | 
			
		||||
        if (status < 0)
 | 
			
		||||
        {
 | 
			
		||||
            qCritical("RTPSink::RTPSink: cannot set destination address: %s", jrtplib::RTPGetErrorString(status).c_str());
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        m_sampleBuffer = new SampleType[sampleRate]; // store 1 second
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~RTPSink()
 | 
			
		||||
    {
 | 
			
		||||
        jrtplib::RTPTime delay = jrtplib::RTPTime(10.0);
 | 
			
		||||
        m_rtpSession.BYEDestroy(delay, "Time's up", 9);
 | 
			
		||||
 | 
			
		||||
        if (m_sampleBuffer) { delete[] m_sampleBuffer; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void setDestination(const QString& address, uint16_t port)
 | 
			
		||||
    {
 | 
			
		||||
        if (!m_sampleBuffer) { return; }
 | 
			
		||||
 | 
			
		||||
        m_rtpSession.ClearDestinations();
 | 
			
		||||
        m_rtpSession.DeleteDestination(jrtplib::RTPIPv4Address(m_destip, m_destport));
 | 
			
		||||
        m_destip = inet_addr(address.toStdString().c_str());
 | 
			
		||||
        m_destip = ntohl(m_destip);
 | 
			
		||||
        m_destport = port;
 | 
			
		||||
 | 
			
		||||
        int status = m_rtpSession.AddDestination(jrtplib::RTPIPv4Address(m_destip, m_destport));
 | 
			
		||||
 | 
			
		||||
        if (status < 0) {
 | 
			
		||||
            qCritical("RTPSink::setDestination: cannot set destination address: %s", jrtplib::RTPGetErrorString(status).c_str());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void deleteDestination(const QString& address, uint16_t port)
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t destip = inet_addr(address.toStdString().c_str());
 | 
			
		||||
        destip = ntohl(m_destip);
 | 
			
		||||
 | 
			
		||||
        int status =  m_rtpSession.DeleteDestination(jrtplib::RTPIPv4Address(destip, port));
 | 
			
		||||
 | 
			
		||||
        if (status < 0) {
 | 
			
		||||
            qCritical("RTPSink::deleteDestination: cannot delete destination address: %s", jrtplib::RTPGetErrorString(status).c_str());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void addDestination(const QString& address, uint16_t port)
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t destip = inet_addr(address.toStdString().c_str());
 | 
			
		||||
        destip = ntohl(m_destip);
 | 
			
		||||
 | 
			
		||||
        int status = m_rtpSession.AddDestination(jrtplib::RTPIPv4Address(destip, port));
 | 
			
		||||
 | 
			
		||||
        if (status < 0) {
 | 
			
		||||
            qCritical("RTPSink::addDestination: cannot add destination address: %s", jrtplib::RTPGetErrorString(status).c_str());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void setSampleRate(int sampleRate)
 | 
			
		||||
    {
 | 
			
		||||
        QMutexLocker locker(&m_mutex);
 | 
			
		||||
        if (m_sampleBuffer) { delete[] m_sampleBuffer; }
 | 
			
		||||
        m_sampleBuffer = new SampleType[sampleRate]; // store 1 second
 | 
			
		||||
 | 
			
		||||
        int status = m_rtpSession.SetTimestampUnit(1.0 / (double) sampleRate);
 | 
			
		||||
 | 
			
		||||
        if (status < 0)
 | 
			
		||||
        {
 | 
			
		||||
            qCritical("RTPSink::setSampleRate: cannot set timestamp unit: %s", jrtplib::RTPGetErrorString(status).c_str());
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    uint32_t m_destip;
 | 
			
		||||
    uint16_t m_destport;
 | 
			
		||||
    jrtplib::RTPSession m_rtpSession;
 | 
			
		||||
    jrtplib::RTPSessionParams m_rtpSessionParams;
 | 
			
		||||
    jrtplib::RTPUDPv4TransmissionParams m_rtpTransmissionParams;
 | 
			
		||||
    SampleType *m_sampleBuffer;
 | 
			
		||||
    int m_sampleBufferIndex;
 | 
			
		||||
    QMutex m_mutex;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* SDRBASE_UTIL_RTPSINK_H_ */
 | 
			
		||||
@ -29,11 +29,11 @@ template<typename T>
 | 
			
		||||
class UDPSink
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	UDPSink(QObject *parent, unsigned int udpSize, unsigned int port) :
 | 
			
		||||
	UDPSink(QObject *parent, unsigned int udpSize) :
 | 
			
		||||
		m_udpSize(udpSize),
 | 
			
		||||
		m_udpSamples(udpSize/sizeof(T)),
 | 
			
		||||
		m_address(QHostAddress::LocalHost),
 | 
			
		||||
		m_port(port),
 | 
			
		||||
		m_port(9999),
 | 
			
		||||
		m_sampleBufferIndex(0)
 | 
			
		||||
	{
 | 
			
		||||
        assert(m_udpSamples > 0);
 | 
			
		||||
@ -41,6 +41,18 @@ public:
 | 
			
		||||
		m_socket = new QUdpSocket(parent);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    UDPSink(QObject *parent, unsigned int udpSize, unsigned int port) :
 | 
			
		||||
        m_udpSize(udpSize),
 | 
			
		||||
        m_udpSamples(udpSize/sizeof(T)),
 | 
			
		||||
        m_address(QHostAddress::LocalHost),
 | 
			
		||||
        m_port(port),
 | 
			
		||||
        m_sampleBufferIndex(0)
 | 
			
		||||
    {
 | 
			
		||||
        assert(m_udpSamples > 0);
 | 
			
		||||
        m_sampleBuffer = new T[m_udpSamples];
 | 
			
		||||
        m_socket = new QUdpSocket(parent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	UDPSink (QObject *parent, unsigned int udpSize, QHostAddress& address, unsigned int port) :
 | 
			
		||||
		m_udpSize(udpSize),
 | 
			
		||||
        m_udpSamples(udpSize/sizeof(T)),
 | 
			
		||||
@ -62,6 +74,12 @@ public:
 | 
			
		||||
	void setAddress(QString& address) { m_address.setAddress(address); }
 | 
			
		||||
	void setPort(unsigned int port) { m_port = port; }
 | 
			
		||||
 | 
			
		||||
	void setDestination(const QString& address, int port)
 | 
			
		||||
	{
 | 
			
		||||
	    m_address.setAddress(const_cast<QString&>(address));
 | 
			
		||||
	    m_port = port;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Write one sample
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user