JackNetTool.cpp 50.6 KB
Newer Older
1
/*
sletz's avatar
sletz committed
2
Copyright (C) 2008-2011 Romain Moret at Grame
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

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; either version 2 of the License, or
(at your option) any later version.

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 for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/
sletz's avatar
sletz committed
19
20

#include "JackNetTool.h"
sletz's avatar
sletz committed
21
#include "JackError.h"
sletz's avatar
sletz committed
22

sletz's avatar
sletz committed
23
24
25
26
27
28
#ifdef __APPLE__

#include <mach/mach_time.h>

class HardwareClock
{
sletz's avatar
sletz committed
29
    public:
sletz's avatar
sletz committed
30

sletz's avatar
sletz committed
31
        HardwareClock();
sletz's avatar
sletz committed
32

sletz's avatar
sletz committed
33
34
        void Reset();
        void Update();
sletz's avatar
sletz committed
35

sletz's avatar
sletz committed
36
37
        float GetDeltaTime() const;
        double GetTime() const;
sletz's avatar
sletz committed
38

sletz's avatar
sletz committed
39
    private:
sletz's avatar
sletz committed
40

sletz's avatar
sletz committed
41
42
43
44
45
46
47
        double m_clockToSeconds;

        uint64_t m_startAbsTime;
        uint64_t m_lastAbsTime;

        double m_time;
        float m_deltaTime;
sletz's avatar
sletz committed
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
};

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

sletz's avatar
sletz committed
88
89
90
91
92
93
using namespace std;

namespace Jack
{
// NetMidiBuffer**********************************************************************************

sletz's avatar
sletz committed
94
    NetMidiBuffer::NetMidiBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
95
96
    {
        fNPorts = nports;
sletz's avatar
sletz committed
97
98
        fMaxBufsize = fNPorts * sizeof(sample_t) * params->fPeriodSize ;
        fMaxPcktSize = params->fMtu - sizeof(packet_header_t);
99
100
        fBuffer = new char[fMaxBufsize];
        fPortBuffer = new JackMidiBuffer* [fNPorts];
sletz's avatar
sletz committed
101
        for (int port_index = 0; port_index < fNPorts; port_index++) {
102
            fPortBuffer[port_index] = NULL;
sletz's avatar
sletz committed
103
        }
104
        fNetBuffer = net_buffer;
sletz's avatar
sletz committed
105

sletz's avatar
sletz committed
106
        fCycleBytesSize = params->fMtu
sletz's avatar
sletz committed
107
108
                * (max(params->fSendMidiChannels, params->fReturnMidiChannels)
                * params->fPeriodSize * sizeof(sample_t) / (params->fMtu - sizeof(packet_header_t)));
109
110
111
112
113
114
115
116
    }

    NetMidiBuffer::~NetMidiBuffer()
    {
        delete[] fBuffer;
        delete[] fPortBuffer;
    }

sletz's avatar
sletz committed
117
    size_t NetMidiBuffer::GetCycleSize()
118
    {
sletz's avatar
sletz committed
119
        return fCycleBytesSize;
sletz's avatar
sletz committed
120
    }
sletz's avatar
sletz committed
121

sletz's avatar
sletz committed
122
    int NetMidiBuffer::GetNumPackets(int data_size, int max_size)
sletz's avatar
sletz committed
123
    {
sletz's avatar
sletz committed
124
125
126
        int res1 = data_size % max_size;
        int res2 = data_size / max_size;
        return (res1) ? res2 + 1 : res2;
127
    }
128

sletz's avatar
sletz committed
129
    void NetMidiBuffer::SetBuffer(int index, JackMidiBuffer* buffer)
sletz's avatar
Cleanup    
sletz committed
130
131
132
    {
        fPortBuffer[index] = buffer;
    }
133

sletz's avatar
sletz committed
134
    JackMidiBuffer* NetMidiBuffer::GetBuffer(int index)
moret's avatar
moret committed
135
136
137
138
    {
        return fPortBuffer[index];
    }

139
140
    void NetMidiBuffer::DisplayEvents()
    {
141
142
        for (int port_index = 0; port_index < fNPorts; port_index++) {
            for (uint event = 0; event < fPortBuffer[port_index]->event_count; event++) {
sletz's avatar
sletz committed
143
                if (fPortBuffer[port_index]->IsValid()) {
sletz's avatar
sletz committed
144
                    jack_info("port %d : midi event %u/%u -> time : %u, size : %u",
145
                                port_index + 1, event + 1, fPortBuffer[port_index]->event_count,
sletz's avatar
sletz committed
146
                                fPortBuffer[port_index]->events[event].time, fPortBuffer[port_index]->events[event].size);
sletz's avatar
sletz committed
147
                }
148
            }
149
150
151
152
153
154
155
        }
    }

    int NetMidiBuffer::RenderFromJackPorts()
    {
        int pos = 0;
        size_t copy_size;
156
157

        for (int port_index = 0; port_index < fNPorts; port_index++) {
158
            char* write_pos = fBuffer + pos;
sletz's avatar
sletz committed
159
160
            copy_size = sizeof(JackMidiBuffer) + fPortBuffer[port_index]->event_count * sizeof(JackMidiEvent);
            memcpy(fBuffer + pos, fPortBuffer[port_index], copy_size);
161
            pos += copy_size;
sletz's avatar
sletz committed
162
163
164
            memcpy(fBuffer + pos,
                    fPortBuffer[port_index] + (fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos),
                    fPortBuffer[port_index]->write_pos);
165
            pos += fPortBuffer[port_index]->write_pos;
166

167
168
            JackMidiBuffer* midi_buffer = reinterpret_cast<JackMidiBuffer*>(write_pos);
            MidiBufferHToN(midi_buffer, midi_buffer);
169
170
171
172
        }
        return pos;
    }

sletz's avatar
sletz committed
173
    void NetMidiBuffer::RenderToJackPorts()
174
175
    {
        int pos = 0;
sletz's avatar
sletz committed
176
        size_t copy_size;
177
178

        for (int port_index = 0; port_index < fNPorts; port_index++) {
179
180
            JackMidiBuffer* midi_buffer = reinterpret_cast<JackMidiBuffer*>(fBuffer + pos);
            MidiBufferNToH(midi_buffer, midi_buffer);
sletz's avatar
sletz committed
181
182
            copy_size = sizeof(JackMidiBuffer) + reinterpret_cast<JackMidiBuffer*>(fBuffer + pos)->event_count * sizeof(JackMidiEvent);
            memcpy(fPortBuffer[port_index], fBuffer + pos, copy_size);
183
            pos += copy_size;
sletz's avatar
sletz committed
184
            memcpy(fPortBuffer[port_index] + (fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos),
sletz's avatar
sletz committed
185
186
                    fBuffer + pos,
                    fPortBuffer[port_index]->write_pos);
187
188
189
            pos += fPortBuffer[port_index]->write_pos;
        }
    }
190

191
    void NetMidiBuffer::RenderFromNetwork(int sub_cycle, size_t copy_size)
192
    {
193
        memcpy(fBuffer + sub_cycle * fMaxPcktSize, fNetBuffer, copy_size);
194
195
    }

196
    int NetMidiBuffer::RenderToNetwork(int sub_cycle, size_t total_size)
197
    {
198
        int size = total_size - sub_cycle * fMaxPcktSize;
sletz's avatar
sletz committed
199
        int copy_size = (size <= fMaxPcktSize) ? size : fMaxPcktSize;
200
        memcpy(fNetBuffer, fBuffer + sub_cycle * fMaxPcktSize, copy_size);
201
202
        return copy_size;
    }
sletz's avatar
sletz committed
203
204
205

// net audio buffer *********************************************************************************

sletz's avatar
sletz committed
206
207
208
209
    NetAudioBuffer::NetAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
    {
        fNPorts = nports;
        fNetBuffer = net_buffer;
Stephane Letz's avatar
Stephane Letz committed
210
        fNumPackets = 0;
sletz's avatar
sletz committed
211

212
        fPortBuffer = new sample_t*[fNPorts];
213
        fConnectedPorts = new bool[fNPorts];
214
        
sletz's avatar
sletz committed
215
        for (int port_index = 0; port_index < fNPorts; port_index++) {
216
217
            fPortBuffer[port_index] = NULL;
            fConnectedPorts[port_index] = true;
sletz's avatar
sletz committed
218
        }
219
220
221
222
223
224
225
        
        fLastSubCycle = 0;
        fPeriodSize = 0;
        fSubPeriodSize = 0;
        fSubPeriodBytesSize = 0;
        fCycleDuration = 0.f;
        fCycleBytesSize = 0;
sletz's avatar
sletz committed
226
    }
227
 
sletz's avatar
sletz committed
228
229
    NetAudioBuffer::~NetAudioBuffer()
    {
230
        delete [] fConnectedPorts;
sletz's avatar
sletz committed
231
232
233
234
235
236
237
238
239
240
241
242
243
        delete [] fPortBuffer;
    }

    void NetAudioBuffer::SetBuffer(int index, sample_t* buffer)
    {
        fPortBuffer[index] = buffer;
    }

    sample_t* NetAudioBuffer::GetBuffer(int index)
    {
        return fPortBuffer[index];
    }

sletz's avatar
sletz committed
244
245
246
247
248
249
    int NetAudioBuffer::CheckPacket(int cycle, int sub_cycle)
    {
        int res;

        if (sub_cycle != fLastSubCycle + 1) {
            jack_error("Packet(s) missing from... %d %d", fLastSubCycle, sub_cycle);
250
            res = DATA_PACKET_ERROR;
sletz's avatar
sletz committed
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
        } else {
            res = 0;
        }

        fLastSubCycle = sub_cycle;
        return res;
    }

    void NetAudioBuffer::NextCycle()
    {
        // reset for next cycle
        fLastSubCycle = -1;
    }

    void NetAudioBuffer::Cleanup()
    {
        for (int port_index = 0; port_index < fNPorts; port_index++) {
            if (fPortBuffer[port_index]) {
                memset(fPortBuffer[port_index], 0, fPeriodSize * sizeof(sample_t));
            }
        }
    }

sletz's avatar
sletz committed
274
275
    //network<->buffer

sletz's avatar
sletz committed
276
    int NetAudioBuffer::ActivePortsToNetwork(char* net_buffer)
sletz's avatar
sletz committed
277
    {
278
279
        int active_ports = 0;
        int* active_port_address = (int*)net_buffer;
sletz's avatar
sletz committed
280

sletz's avatar
sletz committed
281
282
283
        for (int port_index = 0; port_index < fNPorts; port_index++) {
            // Write the active port number
            if (fPortBuffer[port_index]) {
284
                *active_port_address = htonl(port_index);
sletz's avatar
sletz committed
285
                active_port_address++;
286
                active_ports++;
sletz's avatar
sletz committed
287
                assert(active_ports < 256); 
sletz's avatar
sletz committed
288
289
            }
        }
sletz's avatar
sletz committed
290

291
        return active_ports;
sletz's avatar
sletz committed
292
293
    }

sletz's avatar
sletz committed
294
    void NetAudioBuffer::ActivePortsFromNetwork(char* net_buffer, uint32_t port_num)
sletz's avatar
sletz committed
295
    {
296
        int* active_port_address = (int*)net_buffer;
297
  
sletz's avatar
sletz committed
298
        for (int port_index = 0; port_index < fNPorts; port_index++) {
299
            fConnectedPorts[port_index] = false;
sletz's avatar
sletz committed
300
301
302
        }

        for (uint port_index = 0; port_index < port_num; port_index++) {
303
            int active_port = ntohl(*active_port_address);
304
            fConnectedPorts[active_port] = true;
sletz's avatar
sletz committed
305
306
307
308
            active_port_address++;
        }
    }

sletz's avatar
sletz committed
309
    int NetAudioBuffer::RenderFromJackPorts()
310
    {
sletz's avatar
sletz committed
311
312
313
314
315
316
317
        // Count active ports
        int active_ports = 0;
        for (int port_index = 0; port_index < fNPorts; port_index++) {
            if (fPortBuffer[port_index]) {
                active_ports++;
            }
        }
Stephane Letz's avatar
Stephane Letz committed
318
 
sletz's avatar
sletz committed
319
        return active_ports;
320
321
    }

sletz's avatar
sletz committed
322
    void NetAudioBuffer::RenderToJackPorts()
323
    {
sletz's avatar
sletz committed
324
325
        // Nothing to do
        NextCycle();
326
327
    }

sletz's avatar
sletz committed
328
    // Float converter
sletz's avatar
sletz committed
329

sletz's avatar
sletz committed
330
    NetFloatAudioBuffer::NetFloatAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
sletz's avatar
sletz committed
331
        : NetAudioBuffer(params, nports, net_buffer)
sletz's avatar
sletz committed
332
333
    {
        fPeriodSize = params->fPeriodSize;
sletz's avatar
sletz committed
334
        fPacketSize = PACKET_AVAILABLE_SIZE(params);
sletz's avatar
sletz committed
335

sletz's avatar
sletz committed
336
        UpdateParams(max(params->fReturnAudioChannels, params->fSendAudioChannels));
sletz's avatar
sletz committed
337
338
339
340

        fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t);

        fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate);
sletz's avatar
sletz committed
341
        fCycleBytesSize = params->fMtu * (fPeriodSize / fSubPeriodSize);
sletz's avatar
sletz committed
342
343
344
345

        fLastSubCycle = -1;
    }

sletz's avatar
sletz committed
346
    NetFloatAudioBuffer::~NetFloatAudioBuffer()
sletz's avatar
sletz committed
347
    {}
sletz's avatar
sletz committed
348
349

    // needed size in bytes for an entire cycle
sletz's avatar
sletz committed
350
    size_t NetFloatAudioBuffer::GetCycleSize()
sletz's avatar
sletz committed
351
    {
sletz's avatar
sletz committed
352
        return fCycleBytesSize;
sletz's avatar
sletz committed
353
354
355
    }

    // cycle duration in sec
sletz's avatar
sletz committed
356
    float NetFloatAudioBuffer::GetCycleDuration()
sletz's avatar
sletz committed
357
358
359
360
    {
        return fCycleDuration;
    }

sletz's avatar
sletz committed
361
    void NetFloatAudioBuffer::UpdateParams(int active_ports)
sletz's avatar
sletz committed
362
363
364
365
    {
        if (active_ports == 0) {
            fSubPeriodSize = fPeriodSize;
        } else {
366
            jack_nframes_t period = int(powf(2.f, int(log(float(fPacketSize) / (active_ports * sizeof(sample_t))) / log(2.))));
sletz's avatar
sletz committed
367
368
369
            fSubPeriodSize = (period > fPeriodSize) ? fPeriodSize : period;
        }

370
        fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t) + sizeof(int); // The port number in coded on 4 bytes
Stephane Letz's avatar
Stephane Letz committed
371
        fNumPackets = fPeriodSize / fSubPeriodSize; // At least one packet
sletz's avatar
sletz committed
372
373
374
375
376
    }

    int NetFloatAudioBuffer::GetNumPackets(int active_ports)
    {
        UpdateParams(active_ports);
sletz's avatar
sletz committed
377
378

        /*
379
        jack_log("GetNumPackets packet = %d fPeriodSize = %d fSubPeriodSize = %d fSubPeriodBytesSize = %d",
sletz's avatar
sletz committed
380
381
            fPeriodSize / fSubPeriodSize, fPeriodSize, fSubPeriodSize, fSubPeriodBytesSize);
        */
Stephane Letz's avatar
Stephane Letz committed
382
        return fNumPackets;
sletz's avatar
sletz committed
383
384
385
386
    }

    //jack<->buffer

sletz's avatar
sletz committed
387
388
389
390
391
    int NetFloatAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
    {
        // Cleanup all JACK ports at the beginning of the cycle
        if (sub_cycle == 0) {
            Cleanup();
sletz's avatar
sletz committed
392
393
        }

sletz's avatar
sletz committed
394
395
396
397
        if (port_num > 0)  {
            UpdateParams(port_num);
            for (uint32_t port_index = 0; port_index < port_num; port_index++) {
                // Only copy to active ports : read the active port number then audio data
398
                int* active_port_address = (int*)(fNetBuffer + port_index * fSubPeriodBytesSize);
sletz's avatar
sletz committed
399
                int active_port = ntohl(*active_port_address);
400
                RenderFromNetwork((char*)(active_port_address + 1), active_port, sub_cycle);
sletz's avatar
sletz committed
401
402
403
404
            }
        }

        return CheckPacket(cycle, sub_cycle);
sletz's avatar
sletz committed
405
406
    }

sletz's avatar
sletz committed
407
408
    int NetFloatAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
    {
409
        int active_ports = 0;
sletz's avatar
sletz committed
410
411
412
413

        for (int port_index = 0; port_index < fNPorts; port_index++) {
            // Only copy from active ports : write the active port number then audio data
            if (fPortBuffer[port_index]) {
414
                int* active_port_address = (int*)(fNetBuffer + active_ports * fSubPeriodBytesSize);
sletz's avatar
sletz committed
415
                *active_port_address = htonl(port_index);
416
417
                RenderToNetwork((char*)(active_port_address + 1), port_index, sub_cycle);
                active_ports++;
sletz's avatar
sletz committed
418
419
420
421
422
423
            }
        }

        return port_num * fSubPeriodBytesSize;
    }

sletz's avatar
sletz committed
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
#ifdef __BIG_ENDIAN__

    static inline jack_default_audio_sample_t SwapFloat(jack_default_audio_sample_t f)
    {
          union
          {
            jack_default_audio_sample_t f;
            unsigned char b[4];
          } dat1, dat2;

          dat1.f = f;
          dat2.b[0] = dat1.b[3];
          dat2.b[1] = dat1.b[2];
          dat2.b[2] = dat1.b[1];
          dat2.b[3] = dat1.b[0];
          return dat2.f;
    }

    void NetFloatAudioBuffer::RenderFromNetwork(char* net_buffer, int active_port, int sub_cycle)
    {
        if (fPortBuffer[active_port]) {
            jack_default_audio_sample_t* src = (jack_default_audio_sample_t*)(net_buffer);
sletz's avatar
sletz committed
446
            jack_default_audio_sample_t* dst = (jack_default_audio_sample_t*)(fPortBuffer[active_port] + sub_cycle * fSubPeriodSize);
sletz's avatar
sletz committed
447
448
449
450
451
452
453
454
            for (unsigned int sample = 0; sample < (fSubPeriodBytesSize -  sizeof(int)) / sizeof(jack_default_audio_sample_t); sample++) {
                dst[sample] = SwapFloat(src[sample]);
            }
        }
    }

    void NetFloatAudioBuffer::RenderToNetwork(char* net_buffer, int active_port, int sub_cycle)
    {
sletz's avatar
sletz committed
455
        for (int port_index = 0; port_index < fNPorts; port_index++ ) {
sletz's avatar
sletz committed
456
457
458
459
460
461
462
463
464
465
            jack_default_audio_sample_t* src = (jack_default_audio_sample_t*)(fPortBuffer[active_port] + sub_cycle * fSubPeriodSize);
            jack_default_audio_sample_t* dst = (jack_default_audio_sample_t*)(net_buffer);
            for (unsigned int sample = 0; sample < (fSubPeriodBytesSize - sizeof(int)) / sizeof(jack_default_audio_sample_t); sample++) {
                dst[sample] = SwapFloat(src[sample]);
            }
        }
    }

#else

466
    void NetFloatAudioBuffer::RenderFromNetwork(char* net_buffer, int active_port, int sub_cycle)
sletz's avatar
sletz committed
467
    {
468
469
470
        if (fPortBuffer[active_port]) {
            memcpy(fPortBuffer[active_port] + sub_cycle * fSubPeriodSize, net_buffer, fSubPeriodBytesSize - sizeof(int));
        }
sletz's avatar
sletz committed
471
472
    }

473
    void NetFloatAudioBuffer::RenderToNetwork(char* net_buffer, int active_port, int sub_cycle)
sletz's avatar
sletz committed
474
    {
475
        memcpy(net_buffer, fPortBuffer[active_port] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize - sizeof(int));
sletz's avatar
sletz committed
476
477
    }

sletz's avatar
sletz committed
478
#endif
sletz's avatar
sletz committed
479
    // Celt audio buffer *********************************************************************************
sletz's avatar
sletz committed
480

nedko's avatar
nedko committed
481
#if HAVE_CELT
sletz's avatar
sletz committed
482
483
484
485

    #define KPS 32
    #define KPS_DIV 8

sletz's avatar
sletz committed
486
    NetCeltAudioBuffer::NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps)
sletz's avatar
sletz committed
487
        :NetAudioBuffer(params, nports, net_buffer)
488
    {
489
490
491
        fCeltMode = new CELTMode*[fNPorts];
        fCeltEncoder = new CELTEncoder*[fNPorts];
        fCeltDecoder = new CELTDecoder*[fNPorts];
sletz's avatar
sletz committed
492

sletz's avatar
sletz committed
493
494
495
        memset(fCeltMode, 0, fNPorts * sizeof(CELTMode*));
        memset(fCeltEncoder, 0, fNPorts * sizeof(CELTEncoder*));
        memset(fCeltDecoder, 0, fNPorts * sizeof(CELTDecoder*));
sletz's avatar
sletz committed
496

sletz's avatar
sletz committed
497
        int error = CELT_OK;
sletz's avatar
sletz committed
498

sletz's avatar
sletz committed
499
500
        for (int i = 0; i < fNPorts; i++)  {
            fCeltMode[i] = celt_mode_create(params->fSampleRate, params->fPeriodSize, &error);
sletz's avatar
sletz committed
501
            if (error != CELT_OK) {
sletz's avatar
sletz committed
502
                goto error;
sletz's avatar
sletz committed
503
            }
sletz's avatar
sletz committed
504

sletz's avatar
sletz committed
505
506
507
    #if HAVE_CELT_API_0_11

            fCeltEncoder[i] = celt_encoder_create_custom(fCeltMode[i], 1, &error);
sletz's avatar
sletz committed
508
            if (error != CELT_OK) {
sletz's avatar
sletz committed
509
                goto error;
sletz's avatar
sletz committed
510
            }
sletz's avatar
sletz committed
511
512
513
            celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));

            fCeltDecoder[i] = celt_decoder_create_custom(fCeltMode[i], 1, &error);
sletz's avatar
sletz committed
514
            if (error != CELT_OK) {
sletz's avatar
sletz committed
515
                goto error;
sletz's avatar
sletz committed
516
            }
sletz's avatar
sletz committed
517
518
519
520
            celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));

    #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8

sletz's avatar
sletz committed
521
            fCeltEncoder[i] = celt_encoder_create(fCeltMode[i], 1, &error);
sletz's avatar
sletz committed
522
            if (error != CELT_OK) {
sletz's avatar
sletz committed
523
                goto error;
sletz's avatar
sletz committed
524
            }
sletz's avatar
sletz committed
525
            celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));
sletz's avatar
sletz committed
526

sletz's avatar
sletz committed
527
            fCeltDecoder[i] = celt_decoder_create(fCeltMode[i], 1, &error);
sletz's avatar
sletz committed
528
            if (error != CELT_OK) {
sletz's avatar
sletz committed
529
                goto error;
sletz's avatar
sletz committed
530
            }
sletz's avatar
sletz committed
531
            celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));
sletz's avatar
sletz committed
532
533
534
535

    #else

            fCeltEncoder[i] = celt_encoder_create(fCeltMode[i]);
sletz's avatar
sletz committed
536
            if (error != CELT_OK) {
sletz's avatar
sletz committed
537
                goto error;
sletz's avatar
sletz committed
538
            }
sletz's avatar
sletz committed
539
540
541
            celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));

            fCeltDecoder[i] = celt_decoder_create(fCeltMode[i]);
sletz's avatar
sletz committed
542
            if (error != CELT_OK) {
sletz's avatar
sletz committed
543
                goto error;
sletz's avatar
sletz committed
544
            }
sletz's avatar
sletz committed
545
546
547
            celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));

    #endif
sletz's avatar
sletz committed
548
        }
sletz's avatar
sletz committed
549

sletz's avatar
sletz committed
550
551
        {
            fPeriodSize = params->fPeriodSize;
sletz's avatar
sletz committed
552

sletz's avatar
sletz committed
553
554
            fCompressedSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
            jack_log("NetCeltAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte);
sletz's avatar
sletz committed
555

sletz's avatar
sletz committed
556
557
558
            fCompressedBuffer = new unsigned char* [fNPorts];
            for (int port_index = 0; port_index < fNPorts; port_index++) {
                fCompressedBuffer[port_index] = new unsigned char[fCompressedSizeByte];
sletz's avatar
sletz committed
559
                memset(fCompressedBuffer[port_index], 0, fCompressedSizeByte * sizeof(char));
sletz's avatar
sletz committed
560
            }
sletz's avatar
sletz committed
561

sletz's avatar
sletz committed
562
563
            int res1 = (fNPorts * fCompressedSizeByte) % PACKET_AVAILABLE_SIZE(params);
            int res2 = (fNPorts * fCompressedSizeByte) / PACKET_AVAILABLE_SIZE(params);
sletz's avatar
sletz committed
564

sletz's avatar
sletz committed
565
            fNumPackets = (res1) ? (res2 + 1) : res2;
sletz's avatar
sletz committed
566

sletz's avatar
sletz committed
567
            jack_log("NetCeltAudioBuffer res1 = %d res2 = %d", res1, res2);
sletz's avatar
sletz committed
568

sletz's avatar
sletz committed
569
570
            fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
            fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets;
sletz's avatar
sletz committed
571

sletz's avatar
sletz committed
572
            jack_log("NetCeltAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);
sletz's avatar
sletz committed
573

sletz's avatar
sletz committed
574
575
            fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
            fCycleBytesSize = params->fMtu * fNumPackets;
sletz's avatar
sletz committed
576

sletz's avatar
sletz committed
577
578
579
            fLastSubCycle = -1;
            return;
        }
sletz's avatar
sletz committed
580

sletz's avatar
sletz committed
581
    error:
sletz's avatar
sletz committed
582

sletz's avatar
sletz committed
583
584
        FreeCelt();
        throw std::bad_alloc();
585
586
    }

sletz's avatar
sletz committed
587
    NetCeltAudioBuffer::~NetCeltAudioBuffer()
588
    {
sletz's avatar
sletz committed
589
        FreeCelt();
sletz's avatar
sletz committed
590

591
        for (int port_index = 0; port_index < fNPorts; port_index++) {
sletz's avatar
sletz committed
592
            delete [] fCompressedBuffer[port_index];
593
        }
sletz's avatar
sletz committed
594

sletz's avatar
sletz committed
595
        delete [] fCompressedBuffer;
596
597
    }

sletz's avatar
sletz committed
598
    void NetCeltAudioBuffer::FreeCelt()
599
    {
sletz's avatar
sletz committed
600
        for (int i = 0; i < fNPorts; i++)  {
601
            if (fCeltEncoder[i]) {
sletz's avatar
sletz committed
602
                celt_encoder_destroy(fCeltEncoder[i]);
603
604
            }
            if (fCeltDecoder[i]) {
sletz's avatar
sletz committed
605
                celt_decoder_destroy(fCeltDecoder[i]);
606
607
            }
            if (fCeltMode[i]) {
sletz's avatar
sletz committed
608
                celt_mode_destroy(fCeltMode[i]);
609
            }
sletz's avatar
sletz committed
610
        }
sletz's avatar
sletz committed
611

sletz's avatar
sletz committed
612
613
614
615
616
617
618
        delete [] fCeltMode;
        delete [] fCeltEncoder;
        delete [] fCeltDecoder;
    }

    size_t NetCeltAudioBuffer::GetCycleSize()
    {
sletz's avatar
sletz committed
619
        return fCycleBytesSize;
sletz's avatar
sletz committed
620
    }
sletz's avatar
sletz committed
621

sletz's avatar
sletz committed
622
623
624
625
    float NetCeltAudioBuffer::GetCycleDuration()
    {
        return fCycleDuration;
    }
sletz's avatar
sletz committed
626

sletz's avatar
sletz committed
627
    int NetCeltAudioBuffer::GetNumPackets(int active_ports)
sletz's avatar
sletz committed
628
629
    {
        return fNumPackets;
630
    }
631

sletz's avatar
sletz committed
632
    int NetCeltAudioBuffer::RenderFromJackPorts()
633
    {
sletz's avatar
sletz committed
634
        float buffer[BUFFER_SIZE_MAX];
635

sletz's avatar
sletz committed
636
        for (int port_index = 0; port_index < fNPorts; port_index++) {
sletz's avatar
sletz committed
637
638
            if (fPortBuffer[port_index]) {
                memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t));
sletz's avatar
sletz committed
639
640
641
642
643
644
645
646
647
648
            } else {
                memset(buffer, 0, fPeriodSize * sizeof(sample_t));
            }
        #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
            int res = celt_encode_float(fCeltEncoder[port_index], buffer, fPeriodSize, fCompressedBuffer[port_index], fCompressedSizeByte);
        #else
            int res = celt_encode_float(fCeltEncoder[port_index], buffer, NULL, fCompressedBuffer[port_index], fCompressedSizeByte);
        #endif
            if (res != fCompressedSizeByte) {
                jack_error("celt_encode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
sletz's avatar
sletz committed
649
650
            }
        }
sletz's avatar
sletz committed
651
652
653

        // All ports active
        return fNPorts;
654
655
    }

sletz's avatar
sletz committed
656
    void NetCeltAudioBuffer::RenderToJackPorts()
657
    {
sletz's avatar
sletz committed
658
        for (int port_index = 0; port_index < fNPorts; port_index++) {
sletz's avatar
sletz committed
659
660
661
662
663
664
665
666
667
            if (fPortBuffer[port_index]) {
            #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
                int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index], fPeriodSize);
            #else
                int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index]);
            #endif
                if (res != CELT_OK) {
                    jack_error("celt_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
                }
668
669
            }
        }
sletz's avatar
sletz committed
670

sletz's avatar
sletz committed
671
        NextCycle();
672
673
    }

sletz's avatar
sletz committed
674
    //network<->buffer
sletz's avatar
sletz committed
675
    int NetCeltAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
676
    {
sletz's avatar
sletz committed
677
678
679
680
681
        // Cleanup all JACK ports at the beginning of the cycle
        if (sub_cycle == 0) {
            Cleanup();
        }

682
        if (port_num > 0) {
Stephane Letz's avatar
Stephane Letz committed
683
684
685
        
            int sub_period_bytes_size;
            
sletz's avatar
sletz committed
686
687
            // Last packet of the cycle
            if (sub_cycle == fNumPackets - 1) {
Stephane Letz's avatar
Stephane Letz committed
688
                sub_period_bytes_size = fLastSubPeriodBytesSize;
sletz's avatar
sletz committed
689
            } else {
Stephane Letz's avatar
Stephane Letz committed
690
691
692
693
694
                sub_period_bytes_size = fSubPeriodBytesSize;
            }
            
            for (int port_index = 0; port_index < fNPorts; port_index++) {
                memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * sub_period_bytes_size, sub_period_bytes_size);
695
            }
696
        }
sletz's avatar
sletz committed
697

sletz's avatar
sletz committed
698
        return CheckPacket(cycle, sub_cycle);
699
    }
700

sletz's avatar
sletz committed
701
    int NetCeltAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
sletz's avatar
sletz committed
702
    {
Stephane Letz's avatar
Stephane Letz committed
703
704
        int sub_period_bytes_size;
        
705
        // Last packet of the cycle
706
        if (sub_cycle == fNumPackets - 1) {
Stephane Letz's avatar
Stephane Letz committed
707
            sub_period_bytes_size = fLastSubPeriodBytesSize;
sletz's avatar
sletz committed
708
        } else {
Stephane Letz's avatar
Stephane Letz committed
709
710
711
712
713
            sub_period_bytes_size = fSubPeriodBytesSize;
        }
        
        for (int port_index = 0; port_index < fNPorts; port_index++) {
            memcpy(fNetBuffer + port_index * sub_period_bytes_size, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, sub_period_bytes_size);
sletz's avatar
sletz committed
714
        }
Stephane Letz's avatar
Stephane Letz committed
715
        return fNPorts * sub_period_bytes_size;
sletz's avatar
sletz committed
716
717
718
    }

#endif
moret's avatar
moret committed
719

Robin Gareus's avatar
Robin Gareus committed
720
#if HAVE_OPUS
721
#define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length)
Robin Gareus's avatar
Robin Gareus committed
722
723
724
725

    NetOpusAudioBuffer::NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps)
        :NetAudioBuffer(params, nports, net_buffer)
    {
726
727
728
        fOpusMode = new OpusCustomMode*[fNPorts];
        fOpusEncoder = new OpusCustomEncoder*[fNPorts];
        fOpusDecoder = new OpusCustomDecoder*[fNPorts];
729
        fCompressedSizesByte = new unsigned short [fNPorts];
Robin Gareus's avatar
Robin Gareus committed
730
731
732
733

        memset(fOpusMode, 0, fNPorts * sizeof(OpusCustomMode*));
        memset(fOpusEncoder, 0, fNPorts * sizeof(OpusCustomEncoder*));
        memset(fOpusDecoder, 0, fNPorts * sizeof(OpusCustomDecoder*));
734
        memset(fCompressedSizesByte, 0, fNPorts * sizeof(int));
Robin Gareus's avatar
Robin Gareus committed
735
736
737
738
739

        int error = OPUS_OK;

        for (int i = 0; i < fNPorts; i++)  {
            /* Allocate en/decoders */
740
            fOpusMode[i] = opus_custom_mode_create(params->fSampleRate, params->fPeriodSize, &error);
Robin Gareus's avatar
Robin Gareus committed
741
742
743
744
            if (error != OPUS_OK) {
                goto error;
            }

745
            fOpusEncoder[i] = opus_custom_encoder_create(fOpusMode[i], 1, &error);
Robin Gareus's avatar
Robin Gareus committed
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
            if (error != OPUS_OK) {
                goto error;
            }

            fOpusDecoder[i] = opus_custom_decoder_create(fOpusMode[i], 1, &error);
            if (error != OPUS_OK) {
                goto error;
            }

            opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_BITRATE(kbps*1024)); // bits per second
            opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_COMPLEXITY(10));
            opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
            opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
        }

        {
762
            fCompressedMaxSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
Robin Gareus's avatar
Robin Gareus committed
763
            fPeriodSize = params->fPeriodSize;
764
            jack_log("NetOpusAudioBuffer fCompressedMaxSizeByte %d", fCompressedMaxSizeByte);
Robin Gareus's avatar
Robin Gareus committed
765
766
767

            fCompressedBuffer = new unsigned char* [fNPorts];
            for (int port_index = 0; port_index < fNPorts; port_index++) {
768
769
                fCompressedBuffer[port_index] = new unsigned char[fCompressedMaxSizeByte];
                memset(fCompressedBuffer[port_index], 0, fCompressedMaxSizeByte * sizeof(char));
Robin Gareus's avatar
Robin Gareus committed
770
771
            }

772
773
            int res1 = (fNPorts * fCompressedMaxSizeByte + CDO) % PACKET_AVAILABLE_SIZE(params);
            int res2 = (fNPorts * fCompressedMaxSizeByte + CDO) / PACKET_AVAILABLE_SIZE(params);
Robin Gareus's avatar
Robin Gareus committed
774
775
776
777
778

            fNumPackets = (res1) ? (res2 + 1) : res2;

            jack_log("NetOpusAudioBuffer res1 = %d res2 = %d", res1, res2);

779
780
781
            fSubPeriodBytesSize = (fCompressedMaxSizeByte + CDO) / fNumPackets;
            fLastSubPeriodBytesSize = fSubPeriodBytesSize + (fCompressedMaxSizeByte + CDO) % fNumPackets;

Stephane Letz's avatar
Stephane Letz committed
782
783
784
            if (fNumPackets == 1) {
                fSubPeriodBytesSize = fLastSubPeriodBytesSize;
            }
Robin Gareus's avatar
Robin Gareus committed
785
786
787
788
789
790
791

            jack_log("NetOpusAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);

            fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
            fCycleBytesSize = params->fMtu * fNumPackets;

            fLastSubCycle = -1;
Stephane Letz's avatar
Stephane Letz committed
792
            return; 
Robin Gareus's avatar
Robin Gareus committed
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
        }

    error:

        FreeOpus();
        throw std::bad_alloc();
    }

    NetOpusAudioBuffer::~NetOpusAudioBuffer()
    {
        FreeOpus();

        for (int port_index = 0; port_index < fNPorts; port_index++) {
            delete [] fCompressedBuffer[port_index];
        }

        delete [] fCompressedBuffer;
810
        delete [] fCompressedSizesByte;
Robin Gareus's avatar
Robin Gareus committed
811
812
813
814
815
816
817
    }

    void NetOpusAudioBuffer::FreeOpus()
    {
        for (int i = 0; i < fNPorts; i++)  {
            if (fOpusEncoder[i]) {
                opus_custom_encoder_destroy(fOpusEncoder[i]);
818
                fOpusEncoder[i] = 0;
Robin Gareus's avatar
Robin Gareus committed
819
820
821
            }
            if (fOpusDecoder[i]) {
                opus_custom_decoder_destroy(fOpusDecoder[i]);
822
                fOpusDecoder[i] = 0;
Robin Gareus's avatar
Robin Gareus committed
823
824
825
            }
            if (fOpusMode[i]) {
                opus_custom_mode_destroy(fOpusMode[i]);
826
                fOpusMode[i] = 0;
Robin Gareus's avatar
Robin Gareus committed
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
            }
        }

        delete [] fOpusEncoder;
        delete [] fOpusDecoder;
        delete [] fOpusMode;
    }

    size_t NetOpusAudioBuffer::GetCycleSize()
    {
        return fCycleBytesSize;
    }

    float NetOpusAudioBuffer::GetCycleDuration()
    {
        return fCycleDuration;
    }

    int NetOpusAudioBuffer::GetNumPackets(int active_ports)
    {
        return fNumPackets;
    }

    int NetOpusAudioBuffer::RenderFromJackPorts()
    {
        float buffer[BUFFER_SIZE_MAX];

        for (int port_index = 0; port_index < fNPorts; port_index++) {
            if (fPortBuffer[port_index]) {
                memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t));
            } else {
                memset(buffer, 0, fPeriodSize * sizeof(sample_t));
            }
860
            int res = opus_custom_encode_float(fOpusEncoder[port_index], buffer, fPeriodSize, fCompressedBuffer[port_index], fCompressedMaxSizeByte);
861
            if (res < 0 || res >= 65535) {
Stephane Letz's avatar
Stephane Letz committed
862
863
864
865
                fCompressedSizesByte[port_index] = 0;
            } else {
                fCompressedSizesByte[port_index] = res;
            }
Robin Gareus's avatar
Robin Gareus committed
866
867
868
869
870
871
872
873
874
875
        }

        // All ports active
        return fNPorts;
    }

    void NetOpusAudioBuffer::RenderToJackPorts()
    {
        for (int port_index = 0; port_index < fNPorts; port_index++) {
            if (fPortBuffer[port_index]) {
876
                int res = opus_custom_decode_float(fOpusDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizesByte[port_index], fPortBuffer[port_index], fPeriodSize);
877
                if (res < 0 || res != fPeriodSize) {
878
                    jack_error("opus_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizesByte[port_index], res);
Robin Gareus's avatar
Robin Gareus committed
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
                }
            }
        }

        NextCycle();
    }

    //network<->buffer
    int NetOpusAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
    {
        // Cleanup all JACK ports at the beginning of the cycle
        if (sub_cycle == 0) {
            Cleanup();
        }

        if (port_num > 0)  {
895
            if (sub_cycle == 0) {
Robin Gareus's avatar
Robin Gareus committed
896
                for (int port_index = 0; port_index < fNPorts; port_index++) {
897
                    size_t len = *((size_t*)(fNetBuffer + port_index * fSubPeriodBytesSize));
898
                    fCompressedSizesByte[port_index] = ntohs(len);
899
900
901
902
903
                    memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + CDO + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize - CDO);
                }
            } else if (sub_cycle == fNumPackets - 1) {
                for (int port_index = 0; port_index < fNPorts; port_index++) {
                    memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize);
Robin Gareus's avatar
Robin Gareus committed
904
905
906
                }
            } else {
                for (int port_index = 0; port_index < fNPorts; port_index++) {
907
                    memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
Robin Gareus's avatar
Robin Gareus committed
908
909
910
911
912
913
914
915
916
                }
            }
        }

        return CheckPacket(cycle, sub_cycle);
    }

    int NetOpusAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
    {
917
        if (sub_cycle == 0) {
Robin Gareus's avatar
Robin Gareus committed
918
            for (int port_index = 0; port_index < fNPorts; port_index++) {
919
                unsigned short len = htons(fCompressedSizesByte[port_index]);
920
921
922
923
924
925
926
                memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, &len, CDO);
                memcpy(fNetBuffer + port_index * fSubPeriodBytesSize + CDO, fCompressedBuffer[port_index], fSubPeriodBytesSize - CDO);
            }
            return fNPorts * fSubPeriodBytesSize;
        } else if (sub_cycle == fNumPackets - 1) {
            for (int port_index = 0; port_index < fNPorts; port_index++) {
                memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fLastSubPeriodBytesSize);
Robin Gareus's avatar
Robin Gareus committed
927
928
929
930
            }
            return fNPorts * fLastSubPeriodBytesSize;
        } else {
            for (int port_index = 0; port_index < fNPorts; port_index++) {
931
                memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fSubPeriodBytesSize);
Robin Gareus's avatar
Robin Gareus committed
932
933
934
935
936
937
938
            }
            return fNPorts * fSubPeriodBytesSize;
        }
    }

#endif

sletz's avatar
sletz committed
939
    NetIntAudioBuffer::NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
sletz's avatar
sletz committed
940
        : NetAudioBuffer(params, nports, net_buffer)
941
    {
sletz's avatar
sletz committed
942
        fPeriodSize = params->fPeriodSize;
sletz's avatar
sletz committed
943

sletz's avatar
sletz committed
944
945
946
        fCompressedSizeByte = (params->fPeriodSize * sizeof(short));
        jack_log("NetIntAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte);

sletz's avatar
sletz committed
947
        fIntBuffer = new short* [fNPorts];
948
        for (int port_index = 0; port_index < fNPorts; port_index++) {
sletz's avatar
sletz committed
949
            fIntBuffer[port_index] = new short[fPeriodSize];
sletz's avatar
sletz committed
950
            memset(fIntBuffer[port_index], 0, fPeriodSize * sizeof(short));
951
        }
sletz's avatar
sletz committed
952

sletz's avatar
sletz committed
953
954
        int res1 = (fNPorts * fCompressedSizeByte) % PACKET_AVAILABLE_SIZE(params);
        int res2 = (fNPorts * fCompressedSizeByte) / PACKET_AVAILABLE_SIZE(params);
sletz's avatar
sletz committed
955

sletz's avatar
sletz committed
956
        jack_log("NetIntAudioBuffer res1 = %d res2 = %d", res1, res2);
sletz's avatar
sletz committed
957

sletz's avatar
sletz committed
958
        fNumPackets = (res1) ? (res2 + 1) : res2;
sletz's avatar
sletz committed
959

sletz's avatar
sletz committed
960
961
        fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
        fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets;
sletz's avatar
sletz committed
962

sletz's avatar
sletz committed
963
964
965
        fSubPeriodSize = fSubPeriodBytesSize / sizeof(short);

        jack_log("NetIntAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);
sletz's avatar
sletz committed
966

sletz's avatar
sletz committed
967
        fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(