Commit 5b8e976b authored by sletz's avatar sletz
Browse files

Use of CELT codec.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3949 0c269be4-1314-0410-8aa9-9f06e86f4224
parent 3b009644
......@@ -243,9 +243,19 @@ namespace Jack
assert ( fNetMidiCaptureBuffer );
assert ( fNetMidiPlaybackBuffer );
try {
//audio net buffers
fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
#ifdef CELT
fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
#else
fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
#endif
} catch (exception&) {
jack_error("NetAudioBuffer allocation error...");
return false;
}
//fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fTxData );
//fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fRxData );
......@@ -500,7 +510,7 @@ namespace Jack
switch ( rx_head->fDataType )
{
case 'm': //midi
rx_bytes = Recv ( rx_head->fPacketSize, 0 );
rx_bytes = Recv(rx_head->fPacketSize, 0);
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
fNetMidiPlaybackBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
......@@ -510,13 +520,13 @@ namespace Jack
break;
case 'a': //audio
rx_bytes = Recv ( rx_head->fPacketSize, 0 );
rx_bytes = Recv(rx_head->fPacketSize, 0);
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
fNetAudioPlaybackBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
// Last audio packet is received, so finish rendering...
if (fRxHeader.fIsLastPckt)
fNetAudioPlaybackBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
// Last audio packet is received, so finish rendering...
if (fRxHeader.fIsLastPckt)
fNetAudioPlaybackBuffer->RenderToJackPorts();
break;
......@@ -647,9 +657,7 @@ namespace Jack
//utility
session_params_t host_params;
int rx_bytes = 0;
jack_log ( "sizeof (session_params_t) %d", sizeof (session_params_t) );
//socket
if ( fSocket.NewSocket() == SOCKET_ERROR ) {
jack_error ( "Fatal error : network unreachable - %s", StrError ( NET_ERROR_CODE ) );
......@@ -738,12 +746,24 @@ namespace Jack
assert ( fNetMidiPlaybackBuffer );
//audio net buffers
fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
//fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
//fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
//fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
//fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
try {
#ifdef CELT
fNetAudioCaptureBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
fNetAudioPlaybackBuffer = new NetCeltAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
#else
fNetAudioCaptureBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
fNetAudioPlaybackBuffer = new NetSingleAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
//fNetAudioCaptureBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fSendAudioChannels, fRxData );
//fNetAudioPlaybackBuffer = new NetBufferedAudioBuffer ( &fParams, fParams.fReturnAudioChannels, fTxData );
#endif
} catch (exception&) {
jack_error("NetAudioBuffer allocation error...");
return false;
}
assert ( fNetAudioCaptureBuffer );
assert ( fNetAudioPlaybackBuffer );
......@@ -830,7 +850,6 @@ namespace Jack
int JackNetSlaveInterface::DataRecv()
{
int rx_bytes = 0;
//int last_cycle = 0;
uint recvd_midi_pckt = 0;
uint recvd_audio_pckt = 0;
......@@ -850,24 +869,24 @@ namespace Jack
switch ( rx_head->fDataType )
{
case 'm': //midi
rx_bytes = Recv ( rx_head->fPacketSize, 0 );
rx_bytes = Recv(rx_head->fPacketSize, 0);
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
fNetMidiCaptureBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
// Last midi packet is received, so finish rendering...
if ( ++recvd_midi_pckt == rx_head->fNumPacket )
if (++recvd_midi_pckt == rx_head->fNumPacket)
fNetMidiCaptureBuffer->RenderToJackPorts();
break;
case 'a': //audio
rx_bytes = Recv ( rx_head->fPacketSize, 0 );
rx_bytes = Recv(rx_head->fPacketSize, 0);
fRxHeader.fCycle = rx_head->fCycle;
fRxHeader.fSubCycle = rx_head->fSubCycle;
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
fNetAudioCaptureBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
if (fRxHeader.fIsLastPckt) {
// Last audio packet is received, so finish rendering...
if (fRxHeader.fIsLastPckt)
fNetAudioCaptureBuffer->RenderToJackPorts();
}
break;
case 's': //sync
......
......@@ -201,7 +201,6 @@ namespace Jack
}
}
//midi
for ( i = 0; i < fParams.fSendMidiChannels; i++ )
{
......@@ -602,8 +601,6 @@ namespace Jack
if ( fSocket.SetTimeOut ( 2000000 ) == SOCKET_ERROR )
jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
jack_log ( "sizeof (session_params_t) %d", sizeof (session_params_t) );
//main loop, wait for data, deal with it and wait again
do
{
......
......@@ -19,6 +19,72 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackNetTool.h"
#ifdef __APPLE__
#include <mach/mach_time.h>
class HardwareClock
{
public:
HardwareClock();
void Reset();
void Update();
float GetDeltaTime() const;
double GetTime() const;
private:
double m_clockToSeconds;
uint64_t m_startAbsTime;
uint64_t m_lastAbsTime;
double m_time;
float m_deltaTime;
};
HardwareClock::HardwareClock()
{
mach_timebase_info_data_t info;
mach_timebase_info(&info);
m_clockToSeconds = (double)info.numer/info.denom/1000000000.0;
Reset();
}
void HardwareClock::Reset()
{
m_startAbsTime = mach_absolute_time();
m_lastAbsTime = m_startAbsTime;
m_time = m_startAbsTime*m_clockToSeconds;
m_deltaTime = 1.0f/60.0f;
}
void HardwareClock::Update()
{
const uint64_t currentTime = mach_absolute_time();
const uint64_t dt = currentTime - m_lastAbsTime;
m_time = currentTime*m_clockToSeconds;
m_deltaTime = (double)dt*m_clockToSeconds;
m_lastAbsTime = currentTime;
}
float HardwareClock::GetDeltaTime() const
{
return m_deltaTime;
}
double HardwareClock::GetTime() const
{
return m_time;
}
#endif
using namespace std;
namespace Jack
......@@ -46,11 +112,6 @@ namespace Jack
delete[] fPortBuffer;
}
size_t NetMidiBuffer::GetSize()
{
return fMaxBufsize;
}
size_t NetMidiBuffer::GetCycleSize()
{
return fCycleSize;
......@@ -153,11 +214,6 @@ namespace Jack
NetSingleAudioBuffer::~NetSingleAudioBuffer()
{}
size_t NetSingleAudioBuffer::GetSize()
{
return fPortBuffer.GetSize();
}
size_t NetSingleAudioBuffer::GetCycleSize()
{
return fPortBuffer.GetCycleSize();
......@@ -193,6 +249,212 @@ namespace Jack
{
return fPortBuffer.RenderToNetwork(fNetBuffer, subcycle, total_size);
}
// Celt audio buffer *********************************************************************************
#ifdef CELT
#define KPS 32
#define KPS_DIV 8
NetCeltAudioBuffer::NetCeltAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer )
: fNetBuffer(net_buffer)
{
int res1, res2;
jack_nframes_t period;
fNPorts = nports;
fPeriodSize = params->fPeriodSize;
fCeltMode = new CELTMode *[fNPorts];
fCeltEncoder = new CELTEncoder *[fNPorts];
fCeltDecoder = new CELTDecoder *[fNPorts];
memset(fCeltMode, 0, fNPorts * sizeof(CELTMode*));
memset(fCeltEncoder, 0, fNPorts * sizeof(CELTEncoder*));
memset(fCeltDecoder, 0, fNPorts * sizeof(CELTDecoder*));
int error = CELT_OK;
for (int i = 0; i < fNPorts; i++) {
fCeltMode[i] = celt_mode_create(params->fSampleRate, params->fPeriodSize, &error);
if (error != CELT_OK)
goto error;
fCeltEncoder[i] = celt_encoder_create(fCeltMode[i], 1, &error);
if (error != CELT_OK)
goto error;
celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(0));
fCeltDecoder[i] = celt_decoder_create(fCeltMode[i], 1, &error);
if (error != CELT_OK)
goto error;
celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(0));
}
fPortBuffer = new sample_t* [fNPorts];
for (int port_index = 0; port_index < fNPorts; port_index++)
fPortBuffer[port_index] = NULL;
/*
celt_int32 lookahead;
celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead );
*/
//fCompressedSizeByte = (KPS * params->fPeriodSize * 1024 / params->fSampleRate / 8)&(~1);
fCompressedSizeByte = (params->fPeriodSize * sizeof(sample_t)) / KPS_DIV; // TODO
fCompressedBuffer = new unsigned char* [fNPorts];
for (int port_index = 0; port_index < fNPorts; port_index++)
fCompressedBuffer[port_index] = new unsigned char[fCompressedSizeByte];
jack_log("fCompressedSizeByte %d", fCompressedSizeByte);
res1 = (fNPorts * fCompressedSizeByte) % (params->fMtu - sizeof(packet_header_t));
res2 = (fNPorts * fCompressedSizeByte) / (params->fMtu - sizeof(packet_header_t));
jack_log("res1 = %d res2 = %d", res1, res2);
fNumPackets = (res1) ? (res2 + 1) : res2;
fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
fLastSubPeriodBytesSize = fSubPeriodBytesSize + (fCompressedSizeByte - (fSubPeriodBytesSize * fNumPackets));
jack_log("fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);
fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
fCycleSize = params->fMtu * fNumPackets;
fLastSubCycle = -1;
return;
error:
FreeCelt();
throw std::bad_alloc();
}
NetCeltAudioBuffer::~NetCeltAudioBuffer()
{
FreeCelt();
for (int port_index = 0; port_index < fNPorts; port_index++)
delete [] fCompressedBuffer[port_index];
delete [] fCompressedBuffer;
delete [] fPortBuffer;
}
void NetCeltAudioBuffer::FreeCelt()
{
for (int i = 0; i < fNPorts; i++) {
if (fCeltEncoder[i])
celt_encoder_destroy(fCeltEncoder[i]);
if (fCeltDecoder[i])
celt_decoder_destroy(fCeltDecoder[i]);
if (fCeltMode[i])
celt_mode_destroy(fCeltMode[i]);
}
delete [] fCeltMode;
delete [] fCeltEncoder;
delete [] fCeltDecoder;
}
size_t NetCeltAudioBuffer::GetCycleSize()
{
return fCycleSize;
}
float NetCeltAudioBuffer::GetCycleDuration()
{
return fCycleDuration;
}
int NetCeltAudioBuffer::GetNumPackets()
{
return fNumPackets;
}
void NetCeltAudioBuffer::SetBuffer(int index, sample_t* buffer)
{
fPortBuffer[index] = buffer;
}
sample_t* NetCeltAudioBuffer::GetBuffer(int index)
{
return fPortBuffer[index];
}
int NetCeltAudioBuffer::RenderFromJackPorts()
{
float floatbuf[fPeriodSize];
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(floatbuf, fPortBuffer[port_index], fPeriodSize * sizeof(float));
int res = celt_encode_float(fCeltEncoder[port_index], floatbuf, NULL, fCompressedBuffer[port_index], fCompressedSizeByte);
if (res != fCompressedSizeByte) {
jack_error("celt_encode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
}
}
return fNPorts * fCompressedSizeByte; // in bytes
}
int NetCeltAudioBuffer::RenderToJackPorts()
{
for (int port_index = 0; port_index < fNPorts; port_index++) {
int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index]);
if (res != CELT_OK) {
jack_error("celt_decode_float error res = %d", fCompressedSizeByte, res);
}
}
fLastSubCycle = -1;
//return fPeriodSize * sizeof(sample_t); // in bytes; TODO
return 0;
}
HardwareClock clock;
//network<->buffer
int NetCeltAudioBuffer::RenderFromNetwork(int cycle, int subcycle, size_t copy_size)
{
//clock.Update();
if (subcycle == fNumPackets - 1) {
for (int port_index = 0; port_index < fNPorts; port_index++)
memcpy(fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fNetBuffer + port_index * fSubPeriodBytesSize, fLastSubPeriodBytesSize);
} else {
for (int port_index = 0; port_index < fNPorts; port_index++)
memcpy(fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
}
if (subcycle != fLastSubCycle + 1)
jack_error("Packet(s) missing from... %d %d", fLastSubCycle, subcycle);
fLastSubCycle = subcycle;
//clock.Update();
//const float dt = clock.GetDeltaTime();
//printf("Delta: %f s\n", dt);
return copy_size;
}
int NetCeltAudioBuffer::RenderToNetwork(int subcycle, size_t total_size)
{
if (subcycle == fNumPackets - 1) {
for (int port_index = 0; port_index < fNPorts; port_index++)
memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fLastSubPeriodBytesSize);
} else {
for (int port_index = 0; port_index < fNPorts; port_index++)
memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fSubPeriodBytesSize);
}
return fNPorts * fSubPeriodBytesSize;
}
#endif
// Buffered
......@@ -216,11 +478,6 @@ namespace Jack
delete [] fJackPortBuffer;
}
size_t NetBufferedAudioBuffer::GetSize()
{
return fPortBuffer[0].GetSize();
}
size_t NetBufferedAudioBuffer::GetCycleSize()
{
return fPortBuffer[0].GetCycleSize();
......
......@@ -216,6 +216,7 @@ namespace Jack
class SERVER_EXPORT NetMidiBuffer
{
private:
int fNPorts;
size_t fMaxBufsize;
int fMaxPcktSize;
......@@ -226,11 +227,11 @@ namespace Jack
size_t fCycleSize; // needed size in bytes ofr an entire cycle
public:
NetMidiBuffer ( session_params_t* params, uint32_t nports, char* net_buffer );
~NetMidiBuffer();
void Reset();
size_t GetSize();
// needed size in bytes for an entire cycle
size_t GetCycleSize();
......@@ -258,13 +259,12 @@ namespace Jack
{
public:
NetAudioBuffer ()
{}
~NetAudioBuffer()
virtual ~NetAudioBuffer()
{}
virtual size_t GetSize() = 0;
// needed syze in bytes ofr an entire cycle
virtual size_t GetCycleSize() = 0;
......@@ -303,7 +303,7 @@ namespace Jack
sample_t** fPortBuffer;
int fNPorts;
size_t fCycleSize; // needed size in bytes for an entire cycle
float fCycleDuration; // in dec
float fCycleDuration; // in sec
int fLastSubCycle;
......@@ -312,22 +312,22 @@ namespace Jack
fNPorts = nports;
fPeriodSize = params->fPeriodSize;
if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) {
if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) {
fSubPeriodSize = params->fPeriodSize;
} else {
jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float ((params->fMtu - sizeof(packet_header_t)))
/ ( max ( params->fReturnAudioChannels, params->fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) );
fSubPeriodSize = ( period > params->fPeriodSize ) ? params->fPeriodSize : period;
jack_nframes_t period = (int) powf(2.f, (int) (log (float ((params->fMtu - sizeof(packet_header_t)))
/ (max(params->fReturnAudioChannels, params->fSendAudioChannels) * sizeof(sample_t))) / log(2.)));
fSubPeriodSize = (period > params->fPeriodSize) ? params->fPeriodSize : period;
}
fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t );
fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t);
fPortBuffer = new sample_t* [fNPorts];
for ( int port_index = 0; port_index < fNPorts; port_index++ )
for (int port_index = 0; port_index < fNPorts; port_index++)
fPortBuffer[port_index] = NULL;
fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate);
fCycleSize = params->fMtu * ( fPeriodSize / fSubPeriodBytesSize );
fCycleSize = params->fMtu * (fPeriodSize / fSubPeriodSize);
fLastSubCycle = -1;
}
......@@ -363,15 +363,10 @@ namespace Jack
void Copy(sample_t** buffers)
{
for ( int port_index = 0; port_index < fNPorts; port_index++ )
for (int port_index = 0; port_index < fNPorts; port_index++)
memcpy(buffers[port_index], fPortBuffer[port_index], fPeriodSize * sizeof(float));
}
size_t GetSize()
{
return fNPorts * fSubPeriodBytesSize;
}
// needed syze in bytes ofr an entire cycle
size_t GetCycleSize()
{
......@@ -413,7 +408,7 @@ namespace Jack
}
//network<->buffer
int RenderFromNetwork (char* net_buffer, int cycle, int subcycle, size_t copy_size )
int RenderFromNetwork(char* net_buffer, int cycle, int subcycle, size_t copy_size)
{
for ( int port_index = 0; port_index < fNPorts; port_index++ ) {
float* src = (float*)(net_buffer + port_index * fSubPeriodBytesSize);
......@@ -426,7 +421,7 @@ namespace Jack
return copy_size;
}
int RenderToNetwork (char* net_buffer, int subcycle, size_t total_size )
int RenderToNetwork(char* net_buffer, int subcycle, size_t total_size)
{
for ( int port_index = 0; port_index < fNPorts; port_index++ ) {
......@@ -454,10 +449,10 @@ namespace Jack
}
//network<->buffer
int RenderFromNetwork (char* net_buffer, int cycle, int subcycle, size_t copy_size )
int RenderFromNetwork(char* net_buffer, int cycle, int subcycle, size_t copy_size)
{
for ( int port_index = 0; port_index < fNPorts; port_index++ )
memcpy ( fPortBuffer[port_index] + subcycle * fSubPeriodSize, net_buffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize );
for (int port_index = 0; port_index < fNPorts; port_index++)
memcpy(fPortBuffer[port_index] + subcycle * fSubPeriodSize, net_buffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
if (subcycle != fLastSubCycle + 1) {
jack_error("Packet(s) missing from... %d %d", fLastSubCycle, subcycle);
}
......@@ -465,10 +460,10 @@ namespace Jack
return copy_size;
}
int RenderToNetwork (char* net_buffer,int subcycle, size_t total_size )
int RenderToNetwork(char* net_buffer,int subcycle, size_t total_size)
{
for ( int port_index = 0; port_index < fNPorts; port_index++ )
memcpy ( net_buffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize );
for (int port_index = 0; port_index < fNPorts; port_index++)
memcpy(net_buffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize);
return fNPorts * fSubPeriodBytesSize;
}
......@@ -490,7 +485,7 @@ namespace Jack
~JackPortListAllocate()
{
for ( int port_index = 0; port_index < fNPorts; port_index++ )
for (int port_index = 0; port_index < fNPorts; port_index++)
delete [] fPortBuffer[port_index];
delete [] fPortBuffer;
}
......@@ -519,15 +514,15 @@ namespace Jack
class SERVER_EXPORT NetSingleAudioBuffer : public NetAudioBuffer
{
private:
JackPortList fPortBuffer;
char* fNetBuffer;
public: