JackNetTool.cpp 41.3 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
21

#include "JackNetTool.h"

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

#include <mach/mach_time.h>

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

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

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

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

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

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

        uint64_t m_startAbsTime;
        uint64_t m_lastAbsTime;

        double m_time;
        float m_deltaTime;
sletz's avatar
sletz committed
47
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
};

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
87
88
89
90
91
92
using namespace std;

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

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

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

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

sletz's avatar
sletz committed
115
    size_t NetMidiBuffer::GetCycleSize()
116
    {
sletz's avatar
sletz committed
117
118
        return fCycleSize;
    }
sletz's avatar
sletz committed
119

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

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

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

137
138
    void NetMidiBuffer::DisplayEvents()
    {
139
140
        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
141
                if (fPortBuffer[port_index]->IsValid()) {
sletz's avatar
sletz committed
142
                    jack_info("port %d : midi event %u/%u -> time : %u, size : %u",
143
                                port_index + 1, event + 1, fPortBuffer[port_index]->event_count,
sletz's avatar
sletz committed
144
                                fPortBuffer[port_index]->events[event].time, fPortBuffer[port_index]->events[event].size);
sletz's avatar
sletz committed
145
                }
146
            }
147
148
149
150
151
152
153
        }
    }

    int NetMidiBuffer::RenderFromJackPorts()
    {
        int pos = 0;
        size_t copy_size;
154
155

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

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

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

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

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

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

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

sletz's avatar
sletz committed
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
    NetAudioBuffer::NetAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
    {
        fNPorts = nports;
        fNetBuffer = net_buffer;
        fPortBuffer = new sample_t* [fNPorts];
        for (int port_index = 0; port_index < fNPorts; port_index++) {
            fPortBuffer[port_index] = (sample_t*)-1;
        }
    }

    NetAudioBuffer::~NetAudioBuffer()
    {
        delete [] fPortBuffer;
    }

    void NetAudioBuffer::SetBuffer(int index, sample_t* buffer)
    {
        //jack_info("NetAudioBuffer::SetBuffer %d %x", index, buffer);
        fPortBuffer[index] = buffer;
    }

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

sletz's avatar
sletz committed
230
231
    //network<->buffer

sletz's avatar
sletz committed
232
    void NetAudioBuffer::ActivePortsToNetwork(char* net_buffer, uint32_t& port_num)
sletz's avatar
sletz committed
233
234
235
    {
        // Init active port count
        port_num = 0;
sletz's avatar
sletz committed
236
237
238
        short* active_port_address = (short*)net_buffer;

        //jack_info("ActivePortsToNetwork %d", fNPorts);
sletz's avatar
sletz committed
239
240

        for (int port_index = 0; port_index < fNPorts; port_index++) {
sletz's avatar
sletz committed
241
            //jack_info("ActivePortsToNetwork %d", port_index);
sletz's avatar
sletz committed
242
243
            // Write the active port number
            if (fPortBuffer[port_index]) {
sletz's avatar
sletz committed
244
                //jack_info("ActivePortsToNetwork OK %d", port_index);
sletz's avatar
sletz committed
245
246
247
248
249
250
251
252
                *active_port_address = port_index;
                active_port_address++;
                port_num++;
                assert(port_num < 512);
            }
        }
    }

sletz's avatar
sletz committed
253
    void NetAudioBuffer::ActivePortsFromNetwork(char* net_buffer, uint32_t port_num)
sletz's avatar
sletz committed
254
    {
sletz's avatar
sletz committed
255
        short* active_port_address = (short*)net_buffer;
sletz's avatar
sletz committed
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

        for (int port_index = 0; port_index < fNPorts; port_index++) {
            fPortBuffer[port_index] = NULL;
        }

        for (uint port_index = 0; port_index < port_num; port_index++) {
            // Use -1 when port is actually connected on other side
            if (*active_port_address >= 0 && *active_port_address < fNPorts) {
                fPortBuffer[*active_port_address] = (sample_t*)-1;
            } else {
                jack_error("ActivePortsFromNetwork: incorrect port = %d", *active_port_address);
            }
            active_port_address++;
        }
    }

    // Float
sletz's avatar
sletz committed
273
    NetFloatAudioBuffer::NetFloatAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
sletz's avatar
sletz committed
274
275
        : NetAudioBuffer(params, nports, net_buffer), fPortBuffer1(params, nports)
    {}
276

sletz's avatar
sletz committed
277
    NetFloatAudioBuffer::~NetFloatAudioBuffer()
278
279
    {}

sletz's avatar
sletz committed
280
    size_t NetFloatAudioBuffer::GetCycleSize()
sletz's avatar
sletz committed
281
    {
sletz's avatar
sletz committed
282
        return fPortBuffer1.GetCycleSize();
sletz's avatar
sletz committed
283
    }
284

sletz's avatar
sletz committed
285
    void NetFloatAudioBuffer::SetBuffer(int index, sample_t* buffer)
286
    {
sletz's avatar
sletz committed
287
        jack_info("NetAudioBuffer::SetBuffer %d %x", index, buffer);
sletz's avatar
sletz committed
288
        fPortBuffer1.SetBuffer(index, buffer);
289
290
    }

sletz's avatar
sletz committed
291
    sample_t* NetFloatAudioBuffer::GetBuffer(int index)
292
    {
sletz's avatar
sletz committed
293
        return fPortBuffer1.GetBuffer(index);
294
    }
295

sletz's avatar
sletz committed
296
    void NetFloatAudioBuffer::RenderFromJackPorts()
sletz's avatar
Cleanup    
sletz committed
297
    {
sletz's avatar
sletz committed
298
        fPortBuffer1.RenderFromJackPorts();
sletz's avatar
Cleanup    
sletz committed
299
    }
300

sletz's avatar
sletz committed
301
    void NetFloatAudioBuffer::RenderToJackPorts()
sletz's avatar
sletz committed
302
    {
sletz's avatar
sletz committed
303
        fPortBuffer1.RenderToJackPorts();
sletz's avatar
sletz committed
304
    }
sletz's avatar
sletz committed
305

sletz's avatar
sletz committed
306
     //network<->buffer
sletz's avatar
sletz committed
307
    int NetFloatAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num)
sletz's avatar
sletz committed
308
    {
sletz's avatar
sletz committed
309
        return fPortBuffer1.RenderFromNetwork(fNetBuffer, cycle, sub_cycle, copy_size, port_num);
sletz's avatar
sletz committed
310
    }
sletz's avatar
sletz committed
311

sletz's avatar
sletz committed
312
    int NetFloatAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t& port_num)
moret's avatar
moret committed
313
    {
sletz's avatar
sletz committed
314
        return fPortBuffer1.RenderToNetwork(fNetBuffer, sub_cycle, port_num);
moret's avatar
moret committed
315
    }
sletz's avatar
sletz committed
316

317
318
    void NetFloatAudioBuffer::ActivePortsToNetwork(char* net_buffer, uint32_t& port_num)
    {
sletz's avatar
sletz committed
319
        fPortBuffer1.ActivePortsToNetwork(net_buffer, port_num);
320
321
322
323
    }

    void NetFloatAudioBuffer::ActivePortsFromNetwork(char* net_buffer, uint32_t port_num)
    {
sletz's avatar
sletz committed
324
        fPortBuffer1.ActivePortsFromNetwork(net_buffer, port_num);
325
326
    }

sletz's avatar
sletz committed
327
328
329
    // New

    NetFloatAudioBuffer1::NetFloatAudioBuffer1(session_params_t* params, uint32_t nports, char* net_buffer)
sletz's avatar
sletz committed
330
        : NetAudioBuffer(params, nports, net_buffer)
sletz's avatar
sletz committed
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
    {
        fPeriodSize = params->fPeriodSize;
        fPacketSize = params->fMtu - sizeof(packet_header_t);

        if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) {
            fSubPeriodSize = params->fPeriodSize;
        } else {
            jack_nframes_t period = (int) powf(2.f,(int)(log(float(fPacketSize)
                                    / (max(params->fReturnAudioChannels, params->fSendAudioChannels)
                                    * sizeof(sample_t))) / log(2.)));
            fSubPeriodSize = (period > fPeriodSize) ? fPeriodSize : period;
        }

        fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t);

        fPortBuffer = new sample_t* [fNPorts];
        for (int port_index = 0; port_index < fNPorts; port_index++) {
            fPortBuffer[port_index] = NULL;
        }

        fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate);
        fCycleSize = params->fMtu * (fPeriodSize / fSubPeriodSize);

        fLastSubCycle = -1;
    }

    NetFloatAudioBuffer1::~NetFloatAudioBuffer1()
sletz's avatar
sletz committed
358
    {}
sletz's avatar
sletz committed
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451

    // needed size in bytes for an entire cycle
    size_t NetFloatAudioBuffer1::GetCycleSize()
    {
        return fCycleSize;
    }

    // cycle duration in sec
    float NetFloatAudioBuffer1::GetCycleDuration()
    {
        return fCycleDuration;
    }

    int NetFloatAudioBuffer1::GetNumPackets()
    {
        // Count active ports
        int active_ports = 0;
        for (int port_index = 0; port_index < fNPorts; port_index++) {
            if (fPortBuffer[port_index]) active_ports++;
        }

        if (active_ports == 0) {
            fSubPeriodSize = fPeriodSize;
        } else {
            jack_nframes_t period = (int) powf(2.f, (int)(log(float(fPacketSize) / (active_ports * sizeof(sample_t))) / log(2.)));
            fSubPeriodSize = (period > fPeriodSize) ? fPeriodSize : period;
        }

        fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t) + sizeof(uint32_t); // The port number in coded on 4 bytes

        /*
        jack_log("GetNumPackets packet = %d  fPeriodSize = %d fSubPeriodSize = %d fSubPeriodBytesSize = %d",
            fPeriodSize / fSubPeriodSize, fPeriodSize, fSubPeriodSize, fSubPeriodBytesSize);
        */
        return fPeriodSize / fSubPeriodSize; // At least one packet
    }

    //jack<->buffer
    int NetFloatAudioBuffer1::RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num)
    {
        int res = 0;

        // Cleanup all JACK ports at the beginning of the cycle
        if (sub_cycle == 0) {
            for (int port_index = 0; port_index < fNPorts; port_index++) {
                if (fPortBuffer[port_index]) {
                    memset(fPortBuffer[port_index], 0, fPeriodSize * sizeof(sample_t));
                }
            }
        }

        if (port_num > 0)  {

            /// Setup rendering parameters
            int sub_period_size, sub_period_bytes_size;
            if (port_num == 0) {
                sub_period_size = fPeriodSize;
            } else {
                jack_nframes_t period = (int) powf(2.f, (int)(log(float(fPacketSize) / (port_num * sizeof(sample_t))) / log(2.)));
                sub_period_size = (period > fPeriodSize) ? fPeriodSize : period;
            }
            sub_period_bytes_size = sub_period_size * sizeof(sample_t) + sizeof(uint32_t); // The port number in coded on 4 bytes

            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
                uint32_t* active_port_address = (uint32_t*)(fNetBuffer + port_index * sub_period_bytes_size);
                uint32_t active_port = (uint32_t)(*active_port_address);
                if (fPortBuffer[port_index]) {
                    memcpy(fPortBuffer[active_port] + sub_cycle * sub_period_size, (char*)(active_port_address + 1), sub_period_bytes_size - sizeof(uint32_t));
                }
            }

            if (sub_cycle != fLastSubCycle + 1) {
                jack_error("Packet(s) missing from... %d %d", fLastSubCycle, sub_cycle);
                res = NET_PACKET_ERROR;
            }

            fLastSubCycle = sub_cycle;
        }

        return res;
    }

    int NetFloatAudioBuffer1::RenderToNetwork(int sub_cycle, uint32_t& port_num)
    {
        // Init active port count
        port_num = 0;

        //jack_info("NetFloatAudioBuffer1::RenderToNetwork");

        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]) {
sletz's avatar
sletz committed
452
                //jack_info("NetFloatAudioBuffer1::RenderToNetwork %d", port_index);
sletz's avatar
sletz committed
453
454
455
456
457
458
459
460
461
462
                uint32_t* active_port_address = (uint32_t*)(fNetBuffer + port_num * fSubPeriodBytesSize);
                *active_port_address = port_index;
                memcpy((char*)(active_port_address + 1), fPortBuffer[port_index] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize - sizeof(uint32_t));
                port_num++;
            }
        }

        return port_num * fSubPeriodBytesSize;
    }

sletz's avatar
sletz committed
463
    // Celt audio buffer *********************************************************************************
sletz's avatar
sletz committed
464

nedko's avatar
nedko committed
465
#if HAVE_CELT
sletz's avatar
sletz committed
466
467
468
469

    #define KPS 32
    #define KPS_DIV 8

sletz's avatar
sletz committed
470
    NetCeltAudioBuffer::NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps)
sletz's avatar
sletz committed
471
        :NetAudioBuffer(params, nports, net_buffer)
472
    {
sletz's avatar
sletz committed
473
        int res1, res2;
sletz's avatar
sletz committed
474

475
        fPeriodSize = params->fPeriodSize;
sletz's avatar
sletz committed
476

sletz's avatar
sletz committed
477
478
479
        fCeltMode = new CELTMode *[fNPorts];
        fCeltEncoder = new CELTEncoder *[fNPorts];
        fCeltDecoder = new CELTDecoder *[fNPorts];
sletz's avatar
sletz committed
480

sletz's avatar
sletz committed
481
482
483
        memset(fCeltMode, 0, fNPorts * sizeof(CELTMode*));
        memset(fCeltEncoder, 0, fNPorts * sizeof(CELTEncoder*));
        memset(fCeltDecoder, 0, fNPorts * sizeof(CELTDecoder*));
sletz's avatar
sletz committed
484

sletz's avatar
sletz committed
485
        int error = CELT_OK;
sletz's avatar
sletz committed
486

sletz's avatar
sletz committed
487
488
489
490
        for (int i = 0; i < fNPorts; i++)  {
            fCeltMode[i] = celt_mode_create(params->fSampleRate, params->fPeriodSize, &error);
            if (error != CELT_OK)
                goto error;
sletz's avatar
sletz committed
491

sletz's avatar
sletz committed
492
493
494
495
496
497
498
499
500
501
502
503
504
505
    #if HAVE_CELT_API_0_11

            fCeltEncoder[i] = celt_encoder_create_custom(fCeltMode[i], 1, &error);
            if (error != CELT_OK)
                goto error;
            celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));

            fCeltDecoder[i] = celt_decoder_create_custom(fCeltMode[i], 1, &error);
            if (error != CELT_OK)
                goto error;
            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
506
507
508
            fCeltEncoder[i] = celt_encoder_create(fCeltMode[i], 1, &error);
            if (error != CELT_OK)
                goto error;
sletz's avatar
sletz committed
509
            celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));
sletz's avatar
sletz committed
510

sletz's avatar
sletz committed
511
512
513
            fCeltDecoder[i] = celt_decoder_create(fCeltMode[i], 1, &error);
            if (error != CELT_OK)
                goto error;
sletz's avatar
sletz committed
514
            celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));
sletz's avatar
sletz committed
515
516
517
518
519
520
521
522
523
524
525
526
527
528

    #else

            fCeltEncoder[i] = celt_encoder_create(fCeltMode[i]);
            if (error != CELT_OK)
                goto error;
            celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));

            fCeltDecoder[i] = celt_decoder_create(fCeltMode[i]);
            if (error != CELT_OK)
                goto error;
            celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));

    #endif
sletz's avatar
sletz committed
529
        }
sletz's avatar
sletz committed
530

531
        fCompressedSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
sletz's avatar
sletz committed
532

sletz's avatar
sletz committed
533
        fCompressedBuffer = new unsigned char* [fNPorts];
534
        for (int port_index = 0; port_index < fNPorts; port_index++) {
sletz's avatar
sletz committed
535
            fCompressedBuffer[port_index] = new unsigned char[fCompressedSizeByte];
536
        }
sletz's avatar
sletz committed
537

sletz's avatar
sletz committed
538
        jack_log("NetCeltAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte);
sletz's avatar
sletz committed
539

540
541
        res1 = (fNPorts * fCompressedSizeByte) % PACKET_AVAILABLE_SIZE(params);
        res2 = (fNPorts * fCompressedSizeByte) / PACKET_AVAILABLE_SIZE(params);
sletz's avatar
sletz committed
542

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

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

sletz's avatar
sletz committed
547
        fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
sletz's avatar
sletz committed
548
        fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets;
sletz's avatar
sletz committed
549

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

sletz's avatar
sletz committed
552
553
        fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
        fCycleSize = params->fMtu * fNumPackets;
sletz's avatar
sletz committed
554

sletz's avatar
sletz committed
555
556
        fLastSubCycle = -1;
        return;
sletz's avatar
sletz committed
557

sletz's avatar
sletz committed
558
    error:
sletz's avatar
sletz committed
559

sletz's avatar
sletz committed
560
561
        FreeCelt();
        throw std::bad_alloc();
562
563
    }

sletz's avatar
sletz committed
564
    NetCeltAudioBuffer::~NetCeltAudioBuffer()
565
    {
sletz's avatar
sletz committed
566
        FreeCelt();
sletz's avatar
sletz committed
567

568
        for (int port_index = 0; port_index < fNPorts; port_index++) {
sletz's avatar
sletz committed
569
            delete [] fCompressedBuffer[port_index];
570
        }
sletz's avatar
sletz committed
571

sletz's avatar
sletz committed
572
        delete [] fCompressedBuffer;
573
574
    }

sletz's avatar
sletz committed
575
    void NetCeltAudioBuffer::FreeCelt()
576
    {
sletz's avatar
sletz committed
577
        for (int i = 0; i < fNPorts; i++)  {
578
            if (fCeltEncoder[i]) {
sletz's avatar
sletz committed
579
                celt_encoder_destroy(fCeltEncoder[i]);
580
581
            }
            if (fCeltDecoder[i]) {
sletz's avatar
sletz committed
582
                celt_decoder_destroy(fCeltDecoder[i]);
583
584
            }
            if (fCeltMode[i]) {
sletz's avatar
sletz committed
585
                celt_mode_destroy(fCeltMode[i]);
586
            }
sletz's avatar
sletz committed
587
        }
sletz's avatar
sletz committed
588

sletz's avatar
sletz committed
589
590
591
592
593
594
595
596
597
        delete [] fCeltMode;
        delete [] fCeltEncoder;
        delete [] fCeltDecoder;
    }

    size_t NetCeltAudioBuffer::GetCycleSize()
    {
        return fCycleSize;
    }
sletz's avatar
sletz committed
598

sletz's avatar
sletz committed
599
600
601
602
    float NetCeltAudioBuffer::GetCycleDuration()
    {
        return fCycleDuration;
    }
sletz's avatar
sletz committed
603

sletz's avatar
sletz committed
604
605
606
    int NetCeltAudioBuffer::GetNumPackets()
    {
        return fNumPackets;
607
    }
608

sletz's avatar
sletz committed
609
    void NetCeltAudioBuffer::RenderFromJackPorts()
610
    {
sletz's avatar
sletz committed
611
        float floatbuf[fPeriodSize];
612

sletz's avatar
sletz committed
613
614
        for (int port_index = 0; port_index < fNPorts; port_index++) {
            memcpy(floatbuf, fPortBuffer[port_index], fPeriodSize * sizeof(float));
sletz's avatar
sletz committed
615
616
617
#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
            int res = celt_encode_float(fCeltEncoder[port_index], floatbuf, fPeriodSize, fCompressedBuffer[port_index], fCompressedSizeByte);
#else
sletz's avatar
sletz committed
618
            int res = celt_encode_float(fCeltEncoder[port_index], floatbuf, NULL, fCompressedBuffer[port_index], fCompressedSizeByte);
sletz's avatar
sletz committed
619
#endif
sletz's avatar
sletz committed
620
            if (res != fCompressedSizeByte) {
621
                jack_error("celt_encode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
sletz's avatar
sletz committed
622
623
            }
        }
624
625
    }

sletz's avatar
sletz committed
626
    void NetCeltAudioBuffer::RenderToJackPorts()
627
    {
sletz's avatar
sletz committed
628
        for (int port_index = 0; port_index < fNPorts; port_index++) {
sletz's avatar
sletz committed
629
#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
sletz's avatar
sletz committed
630
            int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index], fPeriodSize);
sletz's avatar
sletz committed
631
#else
sletz's avatar
sletz committed
632
            int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index]);
sletz's avatar
sletz committed
633
#endif
sletz's avatar
sletz committed
634
            if (res != CELT_OK) {
635
                jack_error("celt_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
636
637
            }
        }
sletz's avatar
sletz committed
638

sletz's avatar
sletz committed
639
        // reset for next cycle
sletz's avatar
sletz committed
640
        fLastSubCycle = -1;
641
642
    }

sletz's avatar
sletz committed
643
    //network<->buffer
sletz's avatar
sletz committed
644
    int NetCeltAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num)
645
    {
sletz's avatar
sletz committed
646
647
        int res = 0;

648
        // Last packet of the cycle
649
        if (sub_cycle == fNumPackets - 1) {
650
            for (int port_index = 0; port_index < fNPorts; port_index++) {
651
                memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize);
652
            }
sletz's avatar
sletz committed
653
        } else {
654
            for (int port_index = 0; port_index < fNPorts; port_index++) {
655
                memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
656
            }
657
        }
sletz's avatar
sletz committed
658

sletz's avatar
sletz committed
659
        if (sub_cycle != fLastSubCycle + 1) {
660
            jack_error("Packet(s) missing from... %d %d", fLastSubCycle, sub_cycle);
sletz's avatar
sletz committed
661
            res = NET_PACKET_ERROR;
sletz's avatar
sletz committed
662
        }
sletz's avatar
sletz committed
663

664
        fLastSubCycle = sub_cycle;
sletz's avatar
sletz committed
665
        return res;
666
    }
667

sletz's avatar
sletz committed
668
    int NetCeltAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t& port_num)
sletz's avatar
sletz committed
669
    {
670
671
        port_num = fNPorts;

672
        // Last packet of the cycle
673
        if (sub_cycle == fNumPackets - 1) {
674
            for (int port_index = 0; port_index < fNPorts; port_index++) {
675
                memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fLastSubPeriodBytesSize);
676
            }
sletz's avatar
sletz committed
677
            return fNPorts * fLastSubPeriodBytesSize;
sletz's avatar
sletz committed
678
        } else {
679
            for (int port_index = 0; port_index < fNPorts; port_index++) {
680
                memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fSubPeriodBytesSize);
681
            }
sletz's avatar
sletz committed
682
            return fNPorts * fSubPeriodBytesSize;
sletz's avatar
sletz committed
683
684
685
686
        }
    }

#endif
moret's avatar
moret committed
687

sletz's avatar
sletz committed
688
    NetIntAudioBuffer::NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
sletz's avatar
sletz committed
689
        : NetAudioBuffer(params, nports, net_buffer)
690
    {
sletz's avatar
sletz committed
691
        int res1, res2;
sletz's avatar
sletz committed
692

sletz's avatar
sletz committed
693
        fPeriodSize = params->fPeriodSize;
sletz's avatar
sletz committed
694

sletz's avatar
sletz committed
695
        fIntBuffer = new short* [fNPorts];
696
        for (int port_index = 0; port_index < fNPorts; port_index++) {
sletz's avatar
sletz committed
697
            fIntBuffer[port_index] = new short[fPeriodSize];
698
        }
sletz's avatar
sletz committed
699
700
701

        fCompressedSizeByte = (params->fPeriodSize * sizeof(short));

sletz's avatar
sletz committed
702
        jack_log("fCompressedSizeByte %d", fCompressedSizeByte);
sletz's avatar
sletz committed
703

704
705
        res1 = (fNPorts * fCompressedSizeByte) % PACKET_AVAILABLE_SIZE(params);
        res2 = (fNPorts * fCompressedSizeByte) / PACKET_AVAILABLE_SIZE(params);
sletz's avatar
sletz committed
706

sletz's avatar
sletz committed
707
        jack_log("res1 = %d res2 = %d", res1, res2);
sletz's avatar
sletz committed
708

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

sletz's avatar
sletz committed
711
712
        fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
        fSubPeriodSize = fSubPeriodBytesSize / sizeof(short);
sletz's avatar
sletz committed
713

sletz's avatar
sletz committed
714
715
        fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets;
        fLastSubPeriodSize = fLastSubPeriodBytesSize / sizeof(short);
sletz's avatar
sletz committed
716

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

sletz's avatar
sletz committed
719
720
        fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
        fCycleSize = params->fMtu * fNumPackets;
sletz's avatar
sletz committed
721

sletz's avatar
sletz committed
722
723
        fLastSubCycle = -1;
        return;
sletz's avatar
sletz committed
724
    }
sletz's avatar
sletz committed
725
726
727

    NetIntAudioBuffer::~NetIntAudioBuffer()
    {
728
        for (int port_index = 0; port_index < fNPorts; port_index++) {
sletz's avatar
sletz committed
729
            delete [] fIntBuffer[port_index];
730
        }
sletz's avatar
sletz committed
731

sletz's avatar
sletz committed
732
        delete [] fIntBuffer;
733
734
    }

sletz's avatar
sletz committed
735
    size_t NetIntAudioBuffer::GetCycleSize()
736
    {
sletz's avatar
sletz committed
737
        return fCycleSize;
738
    }
sletz's avatar
sletz committed
739

sletz's avatar
sletz committed
740
741
742
743
    float NetIntAudioBuffer::GetCycleDuration()
    {
        return fCycleDuration;
    }
sletz's avatar
sletz committed
744

sletz's avatar
sletz committed
745
746
747
748
749
    int NetIntAudioBuffer::GetNumPackets()
    {
        return fNumPackets;
    }

sletz's avatar
sletz committed
750
    void NetIntAudioBuffer::RenderFromJackPorts()
sletz's avatar
sletz committed
751
752
    {
        for (int port_index = 0; port_index < fNPorts; port_index++) {
753
            for (unsigned int frame = 0; frame < fPeriodSize; frame++) {
sletz's avatar
sletz committed
754
                fIntBuffer[port_index][frame] = short(fPortBuffer[port_index][frame] * 32768.f);
755
            }
sletz's avatar
sletz committed
756
757
758
        }
    }

sletz's avatar
sletz committed
759
    void NetIntAudioBuffer::RenderToJackPorts()
sletz's avatar
sletz committed
760
    {
761
        float coef = 1.f / 32768.f;
sletz's avatar
sletz committed
762
        for (int port_index = 0; port_index < fNPorts; port_index++) {
763
            for (unsigned int frame = 0; frame < fPeriodSize; frame++) {
sletz's avatar
sletz committed
764
                fPortBuffer[port_index][frame] = float(fIntBuffer[port_index][frame] * coef);
765
            }
sletz's avatar
sletz committed
766
        }
sletz's avatar
sletz committed
767

sletz's avatar
sletz committed
768
        // reset for next cycle
sletz's avatar
sletz committed
769
        fLastSubCycle = -1;
sletz's avatar
sletz committed
770
     }
sletz's avatar
sletz committed
771

sletz's avatar
sletz committed
772
     //network<->buffer
sletz's avatar
sletz committed
773
    int NetIntAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num)
sletz's avatar
sletz committed
774
    {
sletz's avatar
sletz committed
775
776
        int res = 0;

777
        if (sub_cycle == fNumPackets - 1) {
778
            for (int port_index = 0; port_index < fNPorts; port_index++) {
779
                memcpy(fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize);
780
            }
sletz's avatar
sletz committed
781
        } else {
782
            for (int port_index = 0; port_index < fNPorts; port_index++) {
783
                memcpy(fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
784
            }
sletz's avatar
sletz committed
785
        }
sletz's avatar
sletz committed
786

sletz's avatar
sletz committed
787
        if (sub_cycle != fLastSubCycle + 1) {
788
            jack_error("Packet(s) missing from... %d %d", fLastSubCycle, sub_cycle);
sletz's avatar
sletz committed
789
            res = NET_PACKET_ERROR;
sletz's avatar
sletz committed
790
        }
sletz's avatar
sletz committed
791

792
        fLastSubCycle = sub_cycle;
sletz's avatar
sletz committed
793
        return res;
sletz's avatar
sletz committed
794
    }
sletz's avatar
sletz committed
795

sletz's avatar
sletz committed
796
    int NetIntAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t& port_num)
sletz's avatar
sletz committed
797
    {
798
799
        port_num = fNPorts;

800
        // Last packet of the cycle
801
        if (sub_cycle == fNumPackets - 1) {
802
            for (int port_index = 0; port_index < fNPorts; port_index++) {
803
                memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fLastSubPeriodBytesSize);
804
            }
sletz's avatar
sletz committed
805
            return fNPorts * fLastSubPeriodBytesSize;
sletz's avatar
sletz committed
806
        } else {
807
            for (int port_index = 0; port_index < fNPorts; port_index++) {
808
                memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize);
809
            }
sletz's avatar
sletz committed
810
            return fNPorts * fSubPeriodBytesSize;
sletz's avatar
sletz committed
811
812
813
        }
    }

sletz's avatar
sletz committed
814
815
// SessionParams ************************************************************************************

sletz's avatar
sletz committed
816
    SERVER_EXPORT void SessionParamsHToN(session_params_t* src_params, session_params_t* dst_params)
817
    {
818
        memcpy(dst_params, src_params, sizeof(session_params_t));
sletz's avatar
sletz committed
819
820
821
822
823
824
825
826
827
828
829
830
        dst_params->fPacketID = htonl(src_params->fPacketID);
        dst_params->fMtu = htonl(src_params->fMtu);
        dst_params->fID = htonl(src_params->fID);
        dst_params->fTransportSync = htonl(src_params->fTransportSync);
        dst_params->fSendAudioChannels = htonl(src_params->fSendAudioChannels);
        dst_params->fReturnAudioChannels = htonl(src_params->fReturnAudioChannels);
        dst_params->fSendMidiChannels = htonl(src_params->fSendMidiChannels);
        dst_params->fReturnMidiChannels = htonl(src_params->fReturnMidiChannels);
        dst_params->fSampleRate = htonl(src_params->fSampleRate);
        dst_params->fPeriodSize = htonl(src_params->fPeriodSize);
        dst_params->fSampleEncoder = htonl(src_params->fSampleEncoder);
        dst_params->fSlaveSyncMode = htonl(src_params->fSlaveSyncMode);
831
        dst_params->fNetworkLatency = htonl(src_params->fNetworkLatency);
sletz's avatar
sletz committed
832
833
834
    }

    SERVER_EXPORT void SessionParamsNToH(session_params_t* src_params, session_params_t* dst_params)
835
    {
836
        memcpy(dst_params, src_params, sizeof(session_params_t));
sletz's avatar
sletz committed
837
838
839
840
841
842
843
844
845
846
847
848
        dst_params->fPacketID = ntohl(src_params->fPacketID);
        dst_params->fMtu = ntohl(src_params->fMtu);
        dst_params->fID = ntohl(src_params->fID);
        dst_params->fTransportSync = ntohl(src_params->fTransportSync);
        dst_params->fSendAudioChannels = ntohl(src_params->fSendAudioChannels);
        dst_params->fReturnAudioChannels = ntohl(src_params->fReturnAudioChannels);
        dst_params->fSendMidiChannels = ntohl(src_params->fSendMidiChannels);
        dst_params->fReturnMidiChannels = ntohl(src_params->fReturnMidiChannels);
        dst_params->fSampleRate = ntohl(src_params->fSampleRate);
        dst_params->fPeriodSize = ntohl(src_params->fPeriodSize);
        dst_params->fSampleEncoder = ntohl(src_params->fSampleEncoder);
        dst_params->fSlaveSyncMode = ntohl(src_params->fSlaveSyncMode);
849
        dst_params->fNetworkLatency = ntohl(src_params->fNetworkLatency);
sletz's avatar
sletz committed
850
851
852
    }

    SERVER_EXPORT void SessionParamsDisplay(session_params_t* params)
853
    {
854
        char encoder[16];
sletz's avatar
sletz committed
855
        switch (params->fSampleEncoder)
856
857
        {
            case JackFloatEncoder:
sletz's avatar
sletz committed
858
                strcpy(encoder, "float");
859
860
                break;
            case JackIntEncoder:
sletz's avatar
sletz committed
861
                strcpy(encoder, "integer");
862
863
                break;
            case JackCeltEncoder:
sletz's avatar
sletz committed
864
                strcpy(encoder, "CELT");
865
866
                break;
        }
sletz's avatar
sletz committed
867

sletz's avatar
sletz committed
868
869
870
871
872
873
874
875
876
877
878
879
        jack_info("**************** Network parameters ****************");
        jack_info("Name : %s", params->fName);
        jack_info("Protocol revision : %d", params->fProtocolVersion);
        jack_info("MTU : %u", params->fMtu);
        jack_info("Master name : %s", params->fMasterNetName);
        jack_info("Slave name : %s", params->fSlaveNetName);
        jack_info("ID : %u", params->fID);
        jack_info("Transport Sync : %s", (params->fTransportSync) ? "yes" : "no");
        jack_info("Send channels (audio - midi) : %d - %d", params->fSendAudioChannels, params->fSendMidiChannels);
        jack_info("Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels);
        jack_info("Sample rate : %u frames per second", params->fSampleRate);
        jack_info("Period size : %u frames per period", params->fPeriodSize);
880
        jack_info("Network latency : %u cycles", params->fNetworkLatency);
sletz's avatar
sletz committed
881
882
        switch (params->fSampleEncoder) {
            case (JackFloatEncoder):
sletz's avatar
sletz committed
883
                jack_info("SampleEncoder : %s", "Float");
sletz's avatar
sletz committed
884
885
                break;
            case (JackIntEncoder):
sletz's avatar
sletz committed
886
                jack_info("SampleEncoder : %s", "16 bits integer");
sletz's avatar
sletz committed
887
888
                break;
            case (JackCeltEncoder):
sletz's avatar
sletz committed
889
890
                jack_info("SampleEncoder : %s", "CELT");
                jack_info("kBits : %d", params->fKBps);
sletz's avatar
sletz committed
891
892
                break;
        };
sletz's avatar
sletz committed
893
894
        jack_info("Slave mode : %s", (params->fSlaveSyncMode) ? "sync" : "async");
        jack_info("****************************************************");
895
896
    }

sletz's avatar
sletz committed
897
    SERVER_EXPORT sync_packet_type_t GetPacketType(session_params_t* params)
898
    {
sletz's avatar
sletz committed
899
        switch (params->fPacketID)
900
        {
901
902
903
904
905
906
907
908
909
910
            case 0:
                return SLAVE_AVAILABLE;
            case 1:
                return SLAVE_SETUP;
            case 2:
                return START_MASTER;
            case 3:
                return START_SLAVE;
            case 4:
                return KILL_MASTER;
911
912
913
914
        }
        return INVALID;
    }