Jack2 1.9.10

JackNetTool.cpp

00001 /*
00002 Copyright (C) 2008-2011 Romain Moret at Grame
00003 
00004 This program is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU General Public License as published by
00006 the Free Software Foundation; either version 2 of the License, or
00007 (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 
00018 */
00019 
00020 #include "JackNetTool.h"
00021 #include "JackError.h"
00022 
00023 #ifdef __APPLE__
00024 
00025 #include <mach/mach_time.h>
00026 
00027 class HardwareClock
00028 {
00029     public:
00030 
00031         HardwareClock();
00032 
00033         void Reset();
00034         void Update();
00035 
00036         float GetDeltaTime() const;
00037         double GetTime() const;
00038 
00039     private:
00040 
00041         double m_clockToSeconds;
00042 
00043         uint64_t m_startAbsTime;
00044         uint64_t m_lastAbsTime;
00045 
00046         double m_time;
00047         float m_deltaTime;
00048 };
00049 
00050 HardwareClock::HardwareClock()
00051 {
00052         mach_timebase_info_data_t info;
00053         mach_timebase_info(&info);
00054         m_clockToSeconds = (double)info.numer/info.denom/1000000000.0;
00055         Reset();
00056 }
00057 
00058 void HardwareClock::Reset()
00059 {
00060         m_startAbsTime = mach_absolute_time();
00061         m_lastAbsTime = m_startAbsTime;
00062         m_time = m_startAbsTime*m_clockToSeconds;
00063         m_deltaTime = 1.0f/60.0f;
00064 }
00065 
00066 void HardwareClock::Update()
00067 {
00068         const uint64_t currentTime = mach_absolute_time();
00069         const uint64_t dt = currentTime - m_lastAbsTime;
00070 
00071         m_time = currentTime*m_clockToSeconds;
00072         m_deltaTime = (double)dt*m_clockToSeconds;
00073         m_lastAbsTime = currentTime;
00074 }
00075 
00076 float HardwareClock::GetDeltaTime() const
00077 {
00078         return m_deltaTime;
00079 }
00080 
00081 double HardwareClock::GetTime() const
00082 {
00083         return m_time;
00084 }
00085 
00086 #endif
00087 
00088 using namespace std;
00089 
00090 namespace Jack
00091 {
00092 // NetMidiBuffer**********************************************************************************
00093 
00094     NetMidiBuffer::NetMidiBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
00095     {
00096         fNPorts = nports;
00097         fMaxBufsize = fNPorts * sizeof(sample_t) * params->fPeriodSize;
00098         fMaxPcktSize = params->fMtu - sizeof(packet_header_t);
00099         fBuffer = new char[fMaxBufsize];
00100         fPortBuffer = new JackMidiBuffer* [fNPorts];
00101         for (int port_index = 0; port_index < fNPorts; port_index++) {
00102             fPortBuffer[port_index] = NULL;
00103         }
00104         fNetBuffer = net_buffer;
00105         fCycleBytesSize = params->fMtu
00106                 * (max(params->fSendMidiChannels, params->fReturnMidiChannels)
00107                 * params->fPeriodSize * sizeof(sample_t) / (params->fMtu - sizeof(packet_header_t)));
00108     }
00109 
00110     NetMidiBuffer::~NetMidiBuffer()
00111     {
00112         delete[] fBuffer;
00113         delete[] fPortBuffer;
00114     }
00115 
00116     size_t NetMidiBuffer::GetCycleSize()
00117     {
00118         return fCycleBytesSize;
00119     }
00120 
00121     int NetMidiBuffer::GetNumPackets(int data_size, int max_size)
00122     {
00123         int res1 = data_size % max_size;
00124         int res2 = data_size / max_size;
00125         return (res1) ? res2 + 1 : res2;
00126     }
00127 
00128     void NetMidiBuffer::SetBuffer(int index, JackMidiBuffer* buffer)
00129     {
00130         fPortBuffer[index] = buffer;
00131     }
00132 
00133     JackMidiBuffer* NetMidiBuffer::GetBuffer(int index)
00134     {
00135         return fPortBuffer[index];
00136     }
00137 
00138     void NetMidiBuffer::DisplayEvents()
00139     {
00140         for (int port_index = 0; port_index < fNPorts; port_index++) {
00141             for (uint event = 0; event < fPortBuffer[port_index]->event_count; event++) {
00142                 if (fPortBuffer[port_index]->IsValid()) {
00143                     jack_info("port %d : midi event %u/%u -> time : %u, size : %u",
00144                                 port_index + 1, event + 1, fPortBuffer[port_index]->event_count,
00145                                 fPortBuffer[port_index]->events[event].time, fPortBuffer[port_index]->events[event].size);
00146                 }
00147             }
00148         }
00149     }
00150 
00151     int NetMidiBuffer::RenderFromJackPorts()
00152     {
00153         int pos = 0;
00154         size_t copy_size;
00155 
00156         for (int port_index = 0; port_index < fNPorts; port_index++) {
00157             char* write_pos = fBuffer + pos;
00158             copy_size = sizeof(JackMidiBuffer) + fPortBuffer[port_index]->event_count * sizeof(JackMidiEvent);
00159             memcpy(fBuffer + pos, fPortBuffer[port_index], copy_size);
00160             pos += copy_size;
00161             memcpy(fBuffer + pos,
00162                     fPortBuffer[port_index] + (fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos),
00163                     fPortBuffer[port_index]->write_pos);
00164             pos += fPortBuffer[port_index]->write_pos;
00165             JackMidiBuffer* midi_buffer = reinterpret_cast<JackMidiBuffer*>(write_pos);
00166             MidiBufferHToN(midi_buffer, midi_buffer);
00167         }
00168         return pos;
00169     }
00170 
00171     void NetMidiBuffer::RenderToJackPorts()
00172     {
00173         int pos = 0;
00174         size_t copy_size;
00175 
00176         for (int port_index = 0; port_index < fNPorts; port_index++) {
00177             JackMidiBuffer* midi_buffer = reinterpret_cast<JackMidiBuffer*>(fBuffer + pos);
00178             MidiBufferNToH(midi_buffer, midi_buffer);
00179             copy_size = sizeof(JackMidiBuffer) + reinterpret_cast<JackMidiBuffer*>(fBuffer + pos)->event_count * sizeof(JackMidiEvent);
00180             memcpy(fPortBuffer[port_index], fBuffer + pos, copy_size);
00181             pos += copy_size;
00182             memcpy(fPortBuffer[port_index] + (fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos),
00183                     fBuffer + pos,
00184                     fPortBuffer[port_index]->write_pos);
00185             pos += fPortBuffer[port_index]->write_pos;
00186         }
00187     }
00188 
00189     void NetMidiBuffer::RenderFromNetwork(int sub_cycle, size_t copy_size)
00190     {
00191         memcpy(fBuffer + sub_cycle * fMaxPcktSize, fNetBuffer, copy_size);
00192     }
00193 
00194     int NetMidiBuffer::RenderToNetwork(int sub_cycle, size_t total_size)
00195     {
00196         int size = total_size - sub_cycle * fMaxPcktSize;
00197         int copy_size = (size <= fMaxPcktSize) ? size : fMaxPcktSize;
00198         memcpy(fNetBuffer, fBuffer + sub_cycle * fMaxPcktSize, copy_size);
00199         return copy_size;
00200     }
00201 
00202 // net audio buffer *********************************************************************************
00203 
00204     NetAudioBuffer::NetAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
00205     {
00206         fNPorts = nports;
00207         fNetBuffer = net_buffer;
00208         fNumPackets = 0;
00209 
00210         fPortBuffer = new sample_t*[fNPorts];
00211         fConnectedPorts = new bool[fNPorts];
00212         
00213         for (int port_index = 0; port_index < fNPorts; port_index++) {
00214             fPortBuffer[port_index] = NULL;
00215             fConnectedPorts[port_index] = true;
00216         }
00217         
00218         fLastSubCycle = 0;
00219         fPeriodSize = 0;
00220         fSubPeriodSize = 0;
00221         fSubPeriodBytesSize = 0;
00222         fCycleDuration = 0.f;
00223         fCycleBytesSize = 0;
00224     }
00225  
00226     NetAudioBuffer::~NetAudioBuffer()
00227     {
00228         delete [] fConnectedPorts;
00229         delete [] fPortBuffer;
00230     }
00231 
00232     void NetAudioBuffer::SetBuffer(int index, sample_t* buffer)
00233     {
00234         fPortBuffer[index] = buffer;
00235     }
00236 
00237     sample_t* NetAudioBuffer::GetBuffer(int index)
00238     {
00239         return fPortBuffer[index];
00240     }
00241 
00242     int NetAudioBuffer::CheckPacket(int cycle, int sub_cycle)
00243     {
00244         int res;
00245 
00246         if (sub_cycle != fLastSubCycle + 1) {
00247             jack_error("Packet(s) missing from... %d %d", fLastSubCycle, sub_cycle);
00248             res = DATA_PACKET_ERROR;
00249         } else {
00250             res = 0;
00251         }
00252 
00253         fLastSubCycle = sub_cycle;
00254         return res;
00255     }
00256 
00257     void NetAudioBuffer::NextCycle()
00258     {
00259         // reset for next cycle
00260         fLastSubCycle = -1;
00261     }
00262 
00263     void NetAudioBuffer::Cleanup()
00264     {
00265         for (int port_index = 0; port_index < fNPorts; port_index++) {
00266             if (fPortBuffer[port_index]) {
00267                 memset(fPortBuffer[port_index], 0, fPeriodSize * sizeof(sample_t));
00268             }
00269         }
00270     }
00271 
00272     //network<->buffer
00273 
00274     int NetAudioBuffer::ActivePortsToNetwork(char* net_buffer)
00275     {
00276         int active_ports = 0;
00277         int* active_port_address = (int*)net_buffer;
00278 
00279         for (int port_index = 0; port_index < fNPorts; port_index++) {
00280             // Write the active port number
00281             if (fPortBuffer[port_index]) {
00282                 *active_port_address = htonl(port_index);
00283                 active_port_address++;
00284                 active_ports++;
00285                 assert(active_ports < 256); 
00286             }
00287         }
00288 
00289         return active_ports;
00290     }
00291 
00292     void NetAudioBuffer::ActivePortsFromNetwork(char* net_buffer, uint32_t port_num)
00293     {
00294         int* active_port_address = (int*)net_buffer;
00295   
00296         for (int port_index = 0; port_index < fNPorts; port_index++) {
00297             fConnectedPorts[port_index] = false;
00298         }
00299 
00300         for (uint port_index = 0; port_index < port_num; port_index++) {
00301             int active_port = ntohl(*active_port_address);
00302             fConnectedPorts[active_port] = true;
00303             active_port_address++;
00304         }
00305     }
00306 
00307     int NetAudioBuffer::RenderFromJackPorts(int unused_frames)
00308     {
00309         // Count active ports
00310         int active_ports = 0;
00311         for (int port_index = 0; port_index < fNPorts; port_index++) {
00312             if (fPortBuffer[port_index]) {
00313                 active_ports++;
00314             }
00315         }
00316  
00317         return active_ports;
00318     }
00319 
00320     void NetAudioBuffer::RenderToJackPorts(int unused_frames)
00321     {
00322         // Nothing to do
00323         NextCycle();
00324     }
00325 
00326     // Float converter
00327 
00328     NetFloatAudioBuffer::NetFloatAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
00329         : NetAudioBuffer(params, nports, net_buffer)
00330     {
00331         fPeriodSize = params->fPeriodSize;
00332         fPacketSize = PACKET_AVAILABLE_SIZE(params);
00333 
00334         UpdateParams(max(params->fReturnAudioChannels, params->fSendAudioChannels));
00335 
00336         fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t);
00337 
00338         fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate);
00339         fCycleBytesSize = params->fMtu * (fPeriodSize / fSubPeriodSize);
00340 
00341         fLastSubCycle = -1;
00342     }
00343 
00344     NetFloatAudioBuffer::~NetFloatAudioBuffer()
00345     {}
00346 
00347     // needed size in bytes for an entire cycle
00348     size_t NetFloatAudioBuffer::GetCycleSize()
00349     {
00350         return fCycleBytesSize;
00351     }
00352 
00353     // cycle duration in sec
00354     float NetFloatAudioBuffer::GetCycleDuration()
00355     {
00356         return fCycleDuration;
00357     }
00358 
00359     void NetFloatAudioBuffer::UpdateParams(int active_ports)
00360     {
00361         if (active_ports == 0) {
00362             fSubPeriodSize = fPeriodSize;
00363         } else {
00364             jack_nframes_t period = int(powf(2.f, int(log(float(fPacketSize) / (active_ports * sizeof(sample_t))) / log(2.))));
00365             fSubPeriodSize = (period > fPeriodSize) ? fPeriodSize : period;
00366         }
00367 
00368         fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t) + sizeof(int); // The port number in coded on 4 bytes
00369         fNumPackets = fPeriodSize / fSubPeriodSize; // At least one packet
00370     }
00371 
00372     int NetFloatAudioBuffer::GetNumPackets(int active_ports)
00373     {
00374         UpdateParams(active_ports);
00375 
00376         /*
00377         jack_log("GetNumPackets packet = %d fPeriodSize = %d fSubPeriodSize = %d fSubPeriodBytesSize = %d",
00378             fPeriodSize / fSubPeriodSize, fPeriodSize, fSubPeriodSize, fSubPeriodBytesSize);
00379         */
00380         return fNumPackets;
00381     }
00382 
00383     //jack<->buffer
00384 
00385     int NetFloatAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
00386     {
00387         // Cleanup all JACK ports at the beginning of the cycle
00388         if (sub_cycle == 0) {
00389             Cleanup();
00390         }
00391 
00392         if (port_num > 0)  {
00393             UpdateParams(port_num);
00394             for (uint32_t port_index = 0; port_index < port_num; port_index++) {
00395                 // Only copy to active ports : read the active port number then audio data
00396                 int* active_port_address = (int*)(fNetBuffer + port_index * fSubPeriodBytesSize);
00397                 int active_port = ntohl(*active_port_address);
00398                 RenderFromNetwork((char*)(active_port_address + 1), active_port, sub_cycle);
00399             }
00400         }
00401 
00402         return CheckPacket(cycle, sub_cycle);
00403     }
00404 
00405     int NetFloatAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
00406     {
00407         int active_ports = 0;
00408 
00409         for (int port_index = 0; port_index < fNPorts; port_index++) {
00410             // Only copy from active ports : write the active port number then audio data
00411             if (fPortBuffer[port_index]) {
00412                 int* active_port_address = (int*)(fNetBuffer + active_ports * fSubPeriodBytesSize);
00413                 *active_port_address = htonl(port_index);
00414                 RenderToNetwork((char*)(active_port_address + 1), port_index, sub_cycle);
00415                 active_ports++;
00416             }
00417         }
00418 
00419         return port_num * fSubPeriodBytesSize;
00420     }
00421 
00422 #ifdef __BIG_ENDIAN__
00423 
00424     static inline jack_default_audio_sample_t SwapFloat(jack_default_audio_sample_t f)
00425     {
00426           union
00427           {
00428             jack_default_audio_sample_t f;
00429             unsigned char b[4];
00430           } dat1, dat2;
00431 
00432           dat1.f = f;
00433           dat2.b[0] = dat1.b[3];
00434           dat2.b[1] = dat1.b[2];
00435           dat2.b[2] = dat1.b[1];
00436           dat2.b[3] = dat1.b[0];
00437           return dat2.f;
00438     }
00439 
00440     void NetFloatAudioBuffer::RenderFromNetwork(char* net_buffer, int active_port, int sub_cycle)
00441     {
00442         if (fPortBuffer[active_port]) {
00443             jack_default_audio_sample_t* src = (jack_default_audio_sample_t*)(net_buffer);
00444             jack_default_audio_sample_t* dst = (jack_default_audio_sample_t*)(fPortBuffer[active_port] + sub_cycle * fSubPeriodSize);
00445             for (unsigned int sample = 0; sample < (fSubPeriodBytesSize -  sizeof(int)) / sizeof(jack_default_audio_sample_t); sample++) {
00446                 dst[sample] = SwapFloat(src[sample]);
00447             }
00448         }
00449     }
00450 
00451     void NetFloatAudioBuffer::RenderToNetwork(char* net_buffer, int active_port, int sub_cycle)
00452     {
00453         for (int port_index = 0; port_index < fNPorts; port_index++ ) {
00454             jack_default_audio_sample_t* src = (jack_default_audio_sample_t*)(fPortBuffer[active_port] + sub_cycle * fSubPeriodSize);
00455             jack_default_audio_sample_t* dst = (jack_default_audio_sample_t*)(net_buffer);
00456             for (unsigned int sample = 0; sample < (fSubPeriodBytesSize - sizeof(int)) / sizeof(jack_default_audio_sample_t); sample++) {
00457                 dst[sample] = SwapFloat(src[sample]);
00458             }
00459         }
00460     }
00461 
00462 #else
00463 
00464     void NetFloatAudioBuffer::RenderFromNetwork(char* net_buffer, int active_port, int sub_cycle)
00465     {
00466         if (fPortBuffer[active_port]) {
00467             memcpy(fPortBuffer[active_port] + sub_cycle * fSubPeriodSize, net_buffer, fSubPeriodBytesSize - sizeof(int));
00468         }
00469     }
00470 
00471     void NetFloatAudioBuffer::RenderToNetwork(char* net_buffer, int active_port, int sub_cycle)
00472     {
00473         memcpy(net_buffer, fPortBuffer[active_port] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize - sizeof(int));
00474     }
00475 
00476 #endif
00477     // Celt audio buffer *********************************************************************************
00478 
00479 #if HAVE_CELT
00480 
00481     #define KPS 32
00482     #define KPS_DIV 8
00483 
00484     NetCeltAudioBuffer::NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps)
00485         :NetAudioBuffer(params, nports, net_buffer)
00486     {
00487         fCeltMode = new CELTMode*[fNPorts];
00488         fCeltEncoder = new CELTEncoder*[fNPorts];
00489         fCeltDecoder = new CELTDecoder*[fNPorts];
00490 
00491         memset(fCeltMode, 0, fNPorts * sizeof(CELTMode*));
00492         memset(fCeltEncoder, 0, fNPorts * sizeof(CELTEncoder*));
00493         memset(fCeltDecoder, 0, fNPorts * sizeof(CELTDecoder*));
00494 
00495         int error = CELT_OK;
00496 
00497         for (int i = 0; i < fNPorts; i++)  {
00498             fCeltMode[i] = celt_mode_create(params->fSampleRate, params->fPeriodSize, &error);
00499             if (error != CELT_OK) {
00500                 jack_log("NetCeltAudioBuffer celt_mode_create err = %d", error);
00501                 goto error;
00502             }
00503 
00504     #if HAVE_CELT_API_0_11
00505 
00506             fCeltEncoder[i] = celt_encoder_create_custom(fCeltMode[i], 1, &error);
00507             if (error != CELT_OK) {
00508                 jack_log("NetCeltAudioBuffer celt_encoder_create_custom err = %d", error);
00509                 goto error;
00510             }
00511             celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));
00512 
00513             fCeltDecoder[i] = celt_decoder_create_custom(fCeltMode[i], 1, &error);
00514             if (error != CELT_OK) {
00515                 jack_log("NetCeltAudioBuffer celt_decoder_create_custom err = %d", error);
00516                 goto error;
00517             }
00518             celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));
00519 
00520     #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
00521 
00522             fCeltEncoder[i] = celt_encoder_create(fCeltMode[i], 1, &error);
00523             if (error != CELT_OK) {
00524                 jack_log("NetCeltAudioBuffer celt_mode_create err = %d", error);
00525                 goto error;
00526             }
00527             celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));
00528 
00529             fCeltDecoder[i] = celt_decoder_create(fCeltMode[i], 1, &error);
00530             if (error != CELT_OK) {
00531                 jack_log("NetCeltAudioBuffer celt_decoder_create err = %d", error);
00532                 goto error;
00533             }
00534             celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));
00535 
00536     #else
00537 
00538             fCeltEncoder[i] = celt_encoder_create(fCeltMode[i]);
00539             if (error != CELT_OK) {
00540                 jack_log("NetCeltAudioBuffer celt_encoder_create err = %d", error);
00541                 goto error;
00542             }
00543             celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));
00544 
00545             fCeltDecoder[i] = celt_decoder_create(fCeltMode[i]);
00546             if (error != CELT_OK) {
00547                 jack_log("NetCeltAudioBuffer celt_decoder_create err = %d", error);
00548                 goto error;
00549             }
00550             celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));
00551 
00552     #endif
00553         }
00554 
00555         {
00556             fPeriodSize = params->fPeriodSize;
00557 
00558             fCompressedSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
00559             jack_log("NetCeltAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte);
00560 
00561             fCompressedBuffer = new unsigned char* [fNPorts];
00562             for (int port_index = 0; port_index < fNPorts; port_index++) {
00563                 fCompressedBuffer[port_index] = new unsigned char[fCompressedSizeByte];
00564                 memset(fCompressedBuffer[port_index], 0, fCompressedSizeByte * sizeof(char));
00565             }
00566 
00567             int res1 = (fNPorts * fCompressedSizeByte) % PACKET_AVAILABLE_SIZE(params);
00568             int res2 = (fNPorts * fCompressedSizeByte) / PACKET_AVAILABLE_SIZE(params);
00569 
00570             fNumPackets = (res1) ? (res2 + 1) : res2;
00571 
00572             jack_log("NetCeltAudioBuffer res1 = %d res2 = %d", res1, res2);
00573 
00574             fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
00575             fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets;
00576 
00577             jack_log("NetCeltAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);
00578 
00579             fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
00580             fCycleBytesSize = params->fMtu * fNumPackets;
00581 
00582             fLastSubCycle = -1;
00583             return;
00584         }
00585 
00586     error:
00587 
00588         FreeCelt();
00589         throw std::bad_alloc();
00590     }
00591 
00592     NetCeltAudioBuffer::~NetCeltAudioBuffer()
00593     {
00594         FreeCelt();
00595 
00596         for (int port_index = 0; port_index < fNPorts; port_index++) {
00597             delete [] fCompressedBuffer[port_index];
00598         }
00599 
00600         delete [] fCompressedBuffer;
00601     }
00602 
00603     void NetCeltAudioBuffer::FreeCelt()
00604     {
00605         for (int i = 0; i < fNPorts; i++)  {
00606             if (fCeltEncoder[i]) {
00607                 celt_encoder_destroy(fCeltEncoder[i]);
00608             }
00609             if (fCeltDecoder[i]) {
00610                 celt_decoder_destroy(fCeltDecoder[i]);
00611             }
00612             if (fCeltMode[i]) {
00613                 celt_mode_destroy(fCeltMode[i]);
00614             }
00615         }
00616 
00617         delete [] fCeltMode;
00618         delete [] fCeltEncoder;
00619         delete [] fCeltDecoder;
00620     }
00621 
00622     size_t NetCeltAudioBuffer::GetCycleSize()
00623     {
00624         return fCycleBytesSize;
00625     }
00626 
00627     float NetCeltAudioBuffer::GetCycleDuration()
00628     {
00629         return fCycleDuration;
00630     }
00631 
00632     int NetCeltAudioBuffer::GetNumPackets(int active_ports)
00633     {
00634         return fNumPackets;
00635     }
00636 
00637     int NetCeltAudioBuffer::RenderFromJackPorts(int nframes)
00638     {
00639         float buffer[BUFFER_SIZE_MAX];
00640 
00641         for (int port_index = 0; port_index < fNPorts; port_index++) {
00642             if (fPortBuffer[port_index]) {
00643                 memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t));
00644             } else {
00645                 memset(buffer, 0, fPeriodSize * sizeof(sample_t));
00646             }
00647         #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
00648             //int res = celt_encode_float(fCeltEncoder[port_index], buffer, fPeriodSize, fCompressedBuffer[port_index], fCompressedSizeByte);
00649             int res = celt_encode_float(fCeltEncoder[port_index], buffer, nframes, fCompressedBuffer[port_index], fCompressedSizeByte);
00650         #else
00651             int res = celt_encode_float(fCeltEncoder[port_index], buffer, NULL, fCompressedBuffer[port_index], fCompressedSizeByte);
00652         #endif
00653             if (res != fCompressedSizeByte) {
00654                 jack_error("celt_encode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
00655             }
00656         }
00657 
00658         // All ports active
00659         return fNPorts;
00660     }
00661 
00662     void NetCeltAudioBuffer::RenderToJackPorts(int nframes)
00663     {
00664         for (int port_index = 0; port_index < fNPorts; port_index++) {
00665             if (fPortBuffer[port_index]) {
00666             #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
00667                 //int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index], fPeriodSize);
00668                 int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index], nframes);
00669             #else
00670                 int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index]);
00671             #endif
00672                 if (res != CELT_OK) {
00673                     jack_error("celt_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
00674                 }
00675             }
00676         }
00677 
00678         NextCycle();
00679     }
00680 
00681     //network<->buffer
00682     int NetCeltAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
00683     {
00684         // Cleanup all JACK ports at the beginning of the cycle
00685         if (sub_cycle == 0) {
00686             Cleanup();
00687         }
00688 
00689         if (port_num > 0) {
00690         
00691             int sub_period_bytes_size;
00692             
00693             // Last packet of the cycle
00694             if (sub_cycle == fNumPackets - 1) {
00695                 sub_period_bytes_size = fLastSubPeriodBytesSize;
00696             } else {
00697                 sub_period_bytes_size = fSubPeriodBytesSize;
00698             }
00699             
00700             for (int port_index = 0; port_index < fNPorts; port_index++) {
00701                 memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * sub_period_bytes_size, sub_period_bytes_size);
00702             }
00703         }
00704 
00705         return CheckPacket(cycle, sub_cycle);
00706     }
00707 
00708     int NetCeltAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
00709     {
00710         int sub_period_bytes_size;
00711         
00712         // Last packet of the cycle
00713         if (sub_cycle == fNumPackets - 1) {
00714             sub_period_bytes_size = fLastSubPeriodBytesSize;
00715         } else {
00716             sub_period_bytes_size = fSubPeriodBytesSize;
00717         }
00718         
00719         for (int port_index = 0; port_index < fNPorts; port_index++) {
00720             memcpy(fNetBuffer + port_index * sub_period_bytes_size, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, sub_period_bytes_size);
00721         }
00722         return fNPorts * sub_period_bytes_size;
00723     }
00724 
00725 #endif
00726 
00727 
00728 #if HAVE_OPUS
00729 #define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length)
00730     NetOpusAudioBuffer::NetOpusAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps)
00731         :NetAudioBuffer(params, nports, net_buffer)
00732     {
00733         fOpusMode = new OpusCustomMode*[fNPorts];
00734         fOpusEncoder = new OpusCustomEncoder*[fNPorts];
00735         fOpusDecoder = new OpusCustomDecoder*[fNPorts];
00736         fCompressedSizesByte = new unsigned short[fNPorts];
00737 
00738         memset(fOpusMode, 0, fNPorts * sizeof(OpusCustomMode*));
00739         memset(fOpusEncoder, 0, fNPorts * sizeof(OpusCustomEncoder*));
00740         memset(fOpusDecoder, 0, fNPorts * sizeof(OpusCustomDecoder*));
00741         memset(fCompressedSizesByte, 0, fNPorts * sizeof(short));
00742 
00743         int error = OPUS_OK;
00744         
00745         for (int i = 0; i < fNPorts; i++)  {
00746             /* Allocate en/decoders */
00747             fOpusMode[i] = opus_custom_mode_create(params->fSampleRate, params->fPeriodSize, &error);
00748             if (error != OPUS_OK) {
00749                 jack_log("NetOpusAudioBuffer opus_custom_mode_create err = %d", error);
00750                 goto error;
00751             }
00752 
00753             fOpusEncoder[i] = opus_custom_encoder_create(fOpusMode[i], 1, &error);
00754             if (error != OPUS_OK) {
00755                 jack_log("NetOpusAudioBuffer opus_custom_encoder_create err = %d", error);
00756                 goto error;
00757             }
00758 
00759             fOpusDecoder[i] = opus_custom_decoder_create(fOpusMode[i], 1, &error);
00760             if (error != OPUS_OK) {
00761                 jack_log("NetOpusAudioBuffer opus_custom_decoder_create err = %d", error);
00762                 goto error;
00763             }
00764 
00765             opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_BITRATE(kbps*1024)); // bits per second
00766             opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_COMPLEXITY(10));
00767             opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
00768             opus_custom_encoder_ctl(fOpusEncoder[i], OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
00769         }
00770 
00771         {
00772             fCompressedMaxSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
00773             fPeriodSize = params->fPeriodSize;
00774             jack_log("NetOpusAudioBuffer fCompressedMaxSizeByte %d", fCompressedMaxSizeByte);
00775 
00776             fCompressedBuffer = new unsigned char* [fNPorts];
00777             for (int port_index = 0; port_index < fNPorts; port_index++) {
00778                 fCompressedBuffer[port_index] = new unsigned char[fCompressedMaxSizeByte];
00779                 memset(fCompressedBuffer[port_index], 0, fCompressedMaxSizeByte * sizeof(char));
00780             }
00781 
00782             int res1 = (fNPorts * fCompressedMaxSizeByte + CDO) % PACKET_AVAILABLE_SIZE(params);
00783             int res2 = (fNPorts * fCompressedMaxSizeByte + CDO) / PACKET_AVAILABLE_SIZE(params);
00784 
00785             fNumPackets = (res1) ? (res2 + 1) : res2;
00786 
00787             jack_log("NetOpusAudioBuffer res1 = %d res2 = %d", res1, res2);
00788 
00789             fSubPeriodBytesSize = (fCompressedMaxSizeByte + CDO) / fNumPackets;
00790             fLastSubPeriodBytesSize = fSubPeriodBytesSize + (fCompressedMaxSizeByte + CDO) % fNumPackets;
00791 
00792             if (fNumPackets == 1) {
00793                 fSubPeriodBytesSize = fLastSubPeriodBytesSize;
00794             }
00795 
00796             jack_log("NetOpusAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);
00797 
00798             fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
00799             fCycleBytesSize = params->fMtu * fNumPackets;
00800 
00801             fLastSubCycle = -1;
00802             return; 
00803         }
00804 
00805     error:
00806 
00807         FreeOpus();
00808         throw std::bad_alloc();
00809     }
00810 
00811     NetOpusAudioBuffer::~NetOpusAudioBuffer()
00812     {
00813         FreeOpus();
00814 
00815         for (int port_index = 0; port_index < fNPorts; port_index++) {
00816             delete [] fCompressedBuffer[port_index];
00817         }
00818 
00819         delete [] fCompressedBuffer;
00820         delete [] fCompressedSizesByte;
00821     }
00822 
00823     void NetOpusAudioBuffer::FreeOpus()
00824     {
00825         for (int i = 0; i < fNPorts; i++)  {
00826             if (fOpusEncoder[i]) {
00827                 opus_custom_encoder_destroy(fOpusEncoder[i]);
00828                 fOpusEncoder[i] = 0;
00829             }
00830             if (fOpusDecoder[i]) {
00831                 opus_custom_decoder_destroy(fOpusDecoder[i]);
00832                 fOpusDecoder[i] = 0;
00833             }
00834             if (fOpusMode[i]) {
00835                 opus_custom_mode_destroy(fOpusMode[i]);
00836                 fOpusMode[i] = 0;
00837             }
00838         }
00839 
00840         delete [] fOpusEncoder;
00841         delete [] fOpusDecoder;
00842         delete [] fOpusMode;
00843     }
00844 
00845     size_t NetOpusAudioBuffer::GetCycleSize()
00846     {
00847         return fCycleBytesSize;
00848     }
00849 
00850     float NetOpusAudioBuffer::GetCycleDuration()
00851     {
00852         return fCycleDuration;
00853     }
00854 
00855     int NetOpusAudioBuffer::GetNumPackets(int active_ports)
00856     {
00857         return fNumPackets;
00858     }
00859 
00860     int NetOpusAudioBuffer::RenderFromJackPorts(int nframes)
00861     {
00862         float buffer[BUFFER_SIZE_MAX];
00863       
00864         for (int port_index = 0; port_index < fNPorts; port_index++) {
00865             if (fPortBuffer[port_index]) {
00866                 memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t));
00867             } else {
00868                 memset(buffer, 0, fPeriodSize * sizeof(sample_t));
00869             }
00870             int res = opus_custom_encode_float(fOpusEncoder[port_index], buffer, ((nframes == -1) ? fPeriodSize : nframes), fCompressedBuffer[port_index], fCompressedMaxSizeByte);
00871             if (res < 0 || res >= 65535) {
00872                 jack_error("opus_custom_encode_float error res = %d", res);
00873                 fCompressedSizesByte[port_index] = 0;
00874             } else {
00875                 fCompressedSizesByte[port_index] = res;
00876             }
00877         }
00878 
00879         // All ports active
00880         return fNPorts;
00881     }
00882 
00883     void NetOpusAudioBuffer::RenderToJackPorts(int nframes)
00884     {
00885         for (int port_index = 0; port_index < fNPorts; port_index++) {
00886             if (fPortBuffer[port_index]) {
00887                 int res = opus_custom_decode_float(fOpusDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizesByte[port_index], fPortBuffer[port_index], ((nframes == -1) ? fPeriodSize : nframes));
00888                 if (res < 0 || res != ((nframes == -1) ? fPeriodSize : nframes)) {
00889                     jack_error("opus_custom_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizesByte[port_index], res);
00890                 }
00891             }
00892         }
00893 
00894         NextCycle();
00895     }
00896 
00897     //network<->buffer
00898     int NetOpusAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
00899     {
00900         // Cleanup all JACK ports at the beginning of the cycle
00901         if (sub_cycle == 0) {
00902             Cleanup();
00903         }
00904 
00905         if (port_num > 0)  {
00906             if (sub_cycle == 0) {
00907                 for (int port_index = 0; port_index < fNPorts; port_index++) {
00908                     size_t len = *((size_t*)(fNetBuffer + port_index * fSubPeriodBytesSize));
00909                     fCompressedSizesByte[port_index] = ntohs(len);
00910                     memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + CDO + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize - CDO);
00911                 }
00912             } else if (sub_cycle == fNumPackets - 1) {
00913                 for (int port_index = 0; port_index < fNPorts; port_index++) {
00914                     memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize);
00915                 }
00916             } else {
00917                 for (int port_index = 0; port_index < fNPorts; port_index++) {
00918                     memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
00919                 }
00920             }
00921         }
00922 
00923         return CheckPacket(cycle, sub_cycle);
00924     }
00925 
00926     int NetOpusAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
00927     {
00928         if (sub_cycle == 0) {
00929             for (int port_index = 0; port_index < fNPorts; port_index++) {
00930                 unsigned short len = htons(fCompressedSizesByte[port_index]);
00931                 memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, &len, CDO);
00932                 memcpy(fNetBuffer + port_index * fSubPeriodBytesSize + CDO, fCompressedBuffer[port_index], fSubPeriodBytesSize - CDO);
00933             }
00934             return fNPorts * fSubPeriodBytesSize;
00935         } else if (sub_cycle == fNumPackets - 1) {
00936             for (int port_index = 0; port_index < fNPorts; port_index++) {
00937                 memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fLastSubPeriodBytesSize);
00938             }
00939             return fNPorts * fLastSubPeriodBytesSize;
00940         } else {
00941             for (int port_index = 0; port_index < fNPorts; port_index++) {
00942                 memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize - CDO, fSubPeriodBytesSize);
00943             }
00944             return fNPorts * fSubPeriodBytesSize;
00945         }
00946     }
00947 
00948 #endif
00949 
00950     NetIntAudioBuffer::NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
00951         : NetAudioBuffer(params, nports, net_buffer)
00952     {
00953         fPeriodSize = params->fPeriodSize;
00954 
00955         fCompressedSizeByte = (params->fPeriodSize * sizeof(short));
00956         jack_log("NetIntAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte);
00957 
00958         fIntBuffer = new short* [fNPorts];
00959         for (int port_index = 0; port_index < fNPorts; port_index++) {
00960             fIntBuffer[port_index] = new short[fPeriodSize];
00961             memset(fIntBuffer[port_index], 0, fPeriodSize * sizeof(short));
00962         }
00963 
00964         int res1 = (fNPorts * fCompressedSizeByte) % PACKET_AVAILABLE_SIZE(params);
00965         int res2 = (fNPorts * fCompressedSizeByte) / PACKET_AVAILABLE_SIZE(params);
00966 
00967         jack_log("NetIntAudioBuffer res1 = %d res2 = %d", res1, res2);
00968 
00969         fNumPackets = (res1) ? (res2 + 1) : res2;
00970 
00971         fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
00972         fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets;
00973 
00974         fSubPeriodSize = fSubPeriodBytesSize / sizeof(short);
00975 
00976         jack_log("NetIntAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);
00977 
00978         fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
00979         fCycleBytesSize = params->fMtu * fNumPackets;
00980 
00981         fLastSubCycle = -1;
00982     }
00983 
00984     NetIntAudioBuffer::~NetIntAudioBuffer()
00985     {
00986         for (int port_index = 0; port_index < fNPorts; port_index++) {
00987             delete [] fIntBuffer[port_index];
00988         }
00989 
00990         delete [] fIntBuffer;
00991     }
00992 
00993     size_t NetIntAudioBuffer::GetCycleSize()
00994     {
00995         return fCycleBytesSize;
00996     }
00997 
00998     float NetIntAudioBuffer::GetCycleDuration()
00999     {
01000         return fCycleDuration;
01001     }
01002 
01003     int NetIntAudioBuffer::GetNumPackets(int active_ports)
01004     {
01005         return fNumPackets;
01006     }
01007     
01008     int NetIntAudioBuffer::RenderFromJackPorts(int nframes)
01009     {
01010         for (int port_index = 0; port_index < fNPorts; port_index++) {
01011             if (fPortBuffer[port_index]) {
01012                 for (int frame = 0; frame < nframes; frame++) {
01013                     fIntBuffer[port_index][frame] = short(fPortBuffer[port_index][frame] * 32767.f);
01014                 }
01015             } else {
01016                 memset(fIntBuffer[port_index], 0, fPeriodSize * sizeof(short));
01017             }
01018         }
01019         
01020         // All ports active
01021         return fNPorts;
01022     }
01023 
01024     void NetIntAudioBuffer::RenderToJackPorts(int nframes)
01025     {
01026         float coef = 1.f / 32767.f;
01027         for (int port_index = 0; port_index < fNPorts; port_index++) {
01028             if (fPortBuffer[port_index]) {
01029                 for (int frame = 0; frame < nframes; frame++) {
01030                     fPortBuffer[port_index][frame] = float(fIntBuffer[port_index][frame] * coef);
01031                 }
01032             }
01033         }
01034 
01035         NextCycle();
01036     }
01037 
01038     //network<->buffer
01039     int NetIntAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
01040     {
01041         // Cleanup all JACK ports at the beginning of the cycle
01042         if (sub_cycle == 0) {
01043             Cleanup();
01044         }
01045 
01046         if (port_num > 0)  {
01047             int sub_period_bytes_size;
01048             
01049             // Last packet
01050             if (sub_cycle == fNumPackets - 1) {
01051                 sub_period_bytes_size = fLastSubPeriodBytesSize;
01052             } else {
01053                 sub_period_bytes_size = fSubPeriodBytesSize;
01054             }
01055             
01056             for (int port_index = 0; port_index < fNPorts; port_index++) {
01057                 memcpy(fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fNetBuffer + port_index * sub_period_bytes_size, sub_period_bytes_size);
01058             }
01059         }
01060 
01061         return CheckPacket(cycle, sub_cycle);
01062     }
01063 
01064     int NetIntAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
01065     {
01066         int sub_period_bytes_size;
01067         
01068         // Last packet
01069         if (sub_cycle == fNumPackets - 1) {
01070             sub_period_bytes_size = fLastSubPeriodBytesSize;
01071         } else {
01072             sub_period_bytes_size = fSubPeriodBytesSize;
01073         }
01074         
01075         for (int port_index = 0; port_index < fNPorts; port_index++) {
01076             memcpy(fNetBuffer + port_index * sub_period_bytes_size, fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, sub_period_bytes_size);
01077         }
01078         return fNPorts * sub_period_bytes_size;
01079     }
01080 
01081 // SessionParams ************************************************************************************
01082 
01083     SERVER_EXPORT void SessionParamsHToN(session_params_t* src_params, session_params_t* dst_params)
01084     {
01085         memcpy(dst_params, src_params, sizeof(session_params_t));
01086         dst_params->fProtocolVersion = htonl(src_params->fProtocolVersion);
01087         dst_params->fPacketID = htonl(src_params->fPacketID);
01088         dst_params->fMtu = htonl(src_params->fMtu);
01089         dst_params->fID = htonl(src_params->fID);
01090         dst_params->fTransportSync = htonl(src_params->fTransportSync);
01091         dst_params->fSendAudioChannels = htonl(src_params->fSendAudioChannels);
01092         dst_params->fReturnAudioChannels = htonl(src_params->fReturnAudioChannels);
01093         dst_params->fSendMidiChannels = htonl(src_params->fSendMidiChannels);
01094         dst_params->fReturnMidiChannels = htonl(src_params->fReturnMidiChannels);
01095         dst_params->fSampleRate = htonl(src_params->fSampleRate);
01096         dst_params->fPeriodSize = htonl(src_params->fPeriodSize);
01097         dst_params->fSampleEncoder = htonl(src_params->fSampleEncoder);
01098         dst_params->fKBps = htonl(src_params->fKBps);
01099         dst_params->fSlaveSyncMode = htonl(src_params->fSlaveSyncMode);
01100         dst_params->fNetworkLatency = htonl(src_params->fNetworkLatency);
01101     }
01102 
01103     SERVER_EXPORT void SessionParamsNToH(session_params_t* src_params, session_params_t* dst_params)
01104     {
01105         memcpy(dst_params, src_params, sizeof(session_params_t));
01106         dst_params->fProtocolVersion = ntohl(src_params->fProtocolVersion);
01107         dst_params->fPacketID = ntohl(src_params->fPacketID);
01108         dst_params->fMtu = ntohl(src_params->fMtu);
01109         dst_params->fID = ntohl(src_params->fID);
01110         dst_params->fTransportSync = ntohl(src_params->fTransportSync);
01111         dst_params->fSendAudioChannels = ntohl(src_params->fSendAudioChannels);
01112         dst_params->fReturnAudioChannels = ntohl(src_params->fReturnAudioChannels);
01113         dst_params->fSendMidiChannels = ntohl(src_params->fSendMidiChannels);
01114         dst_params->fReturnMidiChannels = ntohl(src_params->fReturnMidiChannels);
01115         dst_params->fSampleRate = ntohl(src_params->fSampleRate);
01116         dst_params->fPeriodSize = ntohl(src_params->fPeriodSize);
01117         dst_params->fSampleEncoder = ntohl(src_params->fSampleEncoder);
01118         dst_params->fKBps = ntohl(src_params->fKBps);
01119         dst_params->fSlaveSyncMode = ntohl(src_params->fSlaveSyncMode);
01120         dst_params->fNetworkLatency = ntohl(src_params->fNetworkLatency);
01121     }
01122 
01123     SERVER_EXPORT void SessionParamsDisplay(session_params_t* params)
01124     {
01125         char encoder[16];
01126         switch (params->fSampleEncoder)
01127         {
01128             case JackFloatEncoder:
01129                 strcpy(encoder, "float");
01130                 break;
01131             case JackIntEncoder:
01132                 strcpy(encoder, "integer");
01133                 break;
01134             case JackCeltEncoder:
01135                 strcpy(encoder, "CELT");
01136                 break;
01137             case JackOpusEncoder:
01138                 strcpy(encoder, "OPUS");
01139                 break;
01140         }
01141 
01142         jack_info("**************** Network parameters ****************");
01143         jack_info("Name : %s", params->fName);
01144         jack_info("Protocol revision : %d", params->fProtocolVersion);
01145         jack_info("MTU : %u", params->fMtu);
01146         jack_info("Master name : %s", params->fMasterNetName);
01147         jack_info("Slave name : %s", params->fSlaveNetName);
01148         jack_info("ID : %u", params->fID);
01149         jack_info("Transport Sync : %s", (params->fTransportSync) ? "yes" : "no");
01150         jack_info("Send channels (audio - midi) : %d - %d", params->fSendAudioChannels, params->fSendMidiChannels);
01151         jack_info("Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels);
01152         jack_info("Sample rate : %u frames per second", params->fSampleRate);
01153         jack_info("Period size : %u frames per period", params->fPeriodSize);
01154         jack_info("Network latency : %u cycles", params->fNetworkLatency);
01155         switch (params->fSampleEncoder) {
01156             case (JackFloatEncoder):
01157                 jack_info("SampleEncoder : %s", "Float");
01158                 break;
01159             case (JackIntEncoder):
01160                 jack_info("SampleEncoder : %s", "16 bits integer");
01161                 break;
01162             case (JackCeltEncoder):
01163                 jack_info("SampleEncoder : %s", "CELT");
01164                 jack_info("kBits : %d", params->fKBps);
01165                 break;
01166             case (JackOpusEncoder):
01167                 jack_info("SampleEncoder : %s", "OPUS");
01168                 jack_info("kBits : %d", params->fKBps);
01169                 break;
01170         };
01171         jack_info("Slave mode : %s", (params->fSlaveSyncMode) ? "sync" : "async");
01172         jack_info("****************************************************");
01173     }
01174 
01175     SERVER_EXPORT sync_packet_type_t GetPacketType(session_params_t* params)
01176     {
01177         switch (params->fPacketID)
01178         {
01179             case 0:
01180                 return SLAVE_AVAILABLE;
01181             case 1:
01182                 return SLAVE_SETUP;
01183             case 2:
01184                 return START_MASTER;
01185             case 3:
01186                 return START_SLAVE;
01187             case 4:
01188                 return KILL_MASTER;
01189         }
01190         return INVALID;
01191     }
01192 
01193     SERVER_EXPORT int SetPacketType(session_params_t* params, sync_packet_type_t packet_type)
01194     {
01195         switch (packet_type)
01196         {
01197             case INVALID:
01198                 return -1;
01199             case SLAVE_AVAILABLE:
01200                 params->fPacketID = 0;
01201                 break;
01202             case SLAVE_SETUP:
01203                 params->fPacketID = 1;
01204                 break;
01205             case START_MASTER:
01206                 params->fPacketID = 2;
01207                 break;
01208             case START_SLAVE:
01209                 params->fPacketID = 3;
01210                 break;
01211             case KILL_MASTER:
01212                 params->fPacketID = 4;
01213         }
01214         return 0;
01215     }
01216 
01217 // Packet header **********************************************************************************
01218 
01219     SERVER_EXPORT void PacketHeaderHToN(packet_header_t* src_header, packet_header_t* dst_header)
01220     {
01221         memcpy(dst_header, src_header, sizeof(packet_header_t));
01222         dst_header->fDataType = htonl(src_header->fDataType);
01223         dst_header->fDataStream = htonl(src_header->fDataStream);
01224         dst_header->fID = htonl(src_header->fID);
01225         dst_header->fNumPacket = htonl(src_header->fNumPacket);
01226         dst_header->fPacketSize = htonl(src_header->fPacketSize);
01227         dst_header->fActivePorts = htonl(src_header->fActivePorts);
01228         dst_header->fCycle = htonl(src_header->fCycle);
01229         dst_header->fSubCycle = htonl(src_header->fSubCycle);
01230         dst_header->fFrames = htonl(src_header->fFrames);
01231         dst_header->fIsLastPckt = htonl(src_header->fIsLastPckt);
01232     }
01233 
01234     SERVER_EXPORT void PacketHeaderNToH(packet_header_t* src_header, packet_header_t* dst_header)
01235     {
01236         memcpy(dst_header, src_header, sizeof(packet_header_t));
01237         dst_header->fDataType = ntohl(src_header->fDataType);
01238         dst_header->fDataStream = ntohl(src_header->fDataStream);
01239         dst_header->fID = ntohl(src_header->fID);
01240         dst_header->fNumPacket = ntohl(src_header->fNumPacket);
01241         dst_header->fPacketSize = ntohl(src_header->fPacketSize);
01242         dst_header->fActivePorts = ntohl(src_header->fActivePorts);
01243         dst_header->fCycle = ntohl(src_header->fCycle);
01244         dst_header->fSubCycle = ntohl(src_header->fSubCycle);
01245         dst_header->fFrames = ntohl(src_header->fFrames);
01246         dst_header->fIsLastPckt = ntohl(src_header->fIsLastPckt);
01247     }
01248 
01249     SERVER_EXPORT void PacketHeaderDisplay(packet_header_t* header)
01250     {
01251         jack_info("********************Header********************");
01252         jack_info("Data type : %c", header->fDataType);
01253         jack_info("Data stream : %c", header->fDataStream);
01254         jack_info("ID : %u", header->fID);
01255         jack_info("Cycle : %u", header->fCycle);
01256         jack_info("SubCycle : %u", header->fSubCycle);
01257         jack_info("Active ports : %u", header->fActivePorts);
01258         jack_info("DATA packets : %u", header->fNumPacket);
01259         jack_info("DATA size : %u", header->fPacketSize);
01260         jack_info("DATA frames : %d", header->fFrames);
01261         jack_info("Last packet : '%s'", (header->fIsLastPckt) ? "yes" : "no");
01262         jack_info("**********************************************");
01263     }
01264 
01265     SERVER_EXPORT void NetTransportDataDisplay(net_transport_data_t* data)
01266     {
01267         jack_info("********************Network Transport********************");
01268         jack_info("Transport new state : %u", data->fNewState);
01269         jack_info("Transport timebase master : %u", data->fTimebaseMaster);
01270         jack_info("Transport cycle state : %u", data->fState);
01271         jack_info("**********************************************");
01272     }
01273   
01274     SERVER_EXPORT void MidiBufferHToN(JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer)
01275     {
01276         dst_buffer->magic = htonl(src_buffer->magic);
01277         dst_buffer->buffer_size = htonl(src_buffer->buffer_size);
01278         dst_buffer->nframes = htonl(src_buffer->nframes);
01279         dst_buffer->write_pos = htonl(src_buffer->write_pos);
01280         dst_buffer->event_count = htonl(src_buffer->event_count);
01281         dst_buffer->lost_events = htonl(src_buffer->lost_events);
01282     }
01283 
01284     SERVER_EXPORT void MidiBufferNToH(JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer)
01285     {
01286         dst_buffer->magic = ntohl(src_buffer->magic);
01287         dst_buffer->buffer_size = ntohl(src_buffer->buffer_size);
01288         dst_buffer->nframes = ntohl(src_buffer->nframes);
01289         dst_buffer->write_pos = ntohl(src_buffer->write_pos);
01290         dst_buffer->event_count = ntohl(src_buffer->event_count);
01291         dst_buffer->lost_events = ntohl(src_buffer->lost_events);
01292     }
01293 
01294     SERVER_EXPORT void TransportDataHToN(net_transport_data_t* src_params, net_transport_data_t* dst_params)
01295     {
01296         dst_params->fNewState = htonl(src_params->fNewState);
01297         dst_params->fTimebaseMaster = htonl(src_params->fTimebaseMaster);
01298         dst_params->fState = htonl(src_params->fState);
01299         dst_params->fPosition.unique_1 = htonll(src_params->fPosition.unique_1);
01300         dst_params->fPosition.usecs = htonl(src_params->fPosition.usecs);
01301         dst_params->fPosition.frame_rate = htonl(src_params->fPosition.frame_rate);
01302         dst_params->fPosition.frame = htonl(src_params->fPosition.frame);
01303         dst_params->fPosition.valid = (jack_position_bits_t)htonl((uint32_t)src_params->fPosition.valid);
01304         dst_params->fPosition.bar = htonl(src_params->fPosition.bar);
01305         dst_params->fPosition.beat = htonl(src_params->fPosition.beat);
01306         dst_params->fPosition.tick = htonl(src_params->fPosition.tick);
01307         dst_params->fPosition.bar_start_tick = htonll((uint64_t)src_params->fPosition.bar_start_tick);
01308         dst_params->fPosition.beats_per_bar = htonl((uint32_t)src_params->fPosition.beats_per_bar);
01309         dst_params->fPosition.beat_type = htonl((uint32_t)src_params->fPosition.beat_type);
01310         dst_params->fPosition.ticks_per_beat = htonll((uint64_t)src_params->fPosition.ticks_per_beat);
01311         dst_params->fPosition.beats_per_minute = htonll((uint64_t)src_params->fPosition.beats_per_minute);
01312         dst_params->fPosition.frame_time = htonll((uint64_t)src_params->fPosition.frame_time);
01313         dst_params->fPosition.next_time = htonll((uint64_t)src_params->fPosition.next_time);
01314         dst_params->fPosition.bbt_offset = htonl(src_params->fPosition.bbt_offset);
01315         dst_params->fPosition.audio_frames_per_video_frame = htonl((uint32_t)src_params->fPosition.audio_frames_per_video_frame);
01316         dst_params->fPosition.video_offset = htonl(src_params->fPosition.video_offset);
01317         dst_params->fPosition.unique_2 = htonll(src_params->fPosition.unique_2);
01318     }
01319 
01320     SERVER_EXPORT void TransportDataNToH(net_transport_data_t* src_params, net_transport_data_t* dst_params)
01321     {
01322         dst_params->fNewState = ntohl(src_params->fNewState);
01323         dst_params->fTimebaseMaster =  ntohl(src_params->fTimebaseMaster);
01324         dst_params->fState = ntohl(src_params->fState);
01325         dst_params->fPosition.unique_1 = ntohll(src_params->fPosition.unique_1);
01326         dst_params->fPosition.usecs = ntohl(src_params->fPosition.usecs);
01327         dst_params->fPosition.frame_rate = ntohl(src_params->fPosition.frame_rate);
01328         dst_params->fPosition.frame = ntohl(src_params->fPosition.frame);
01329         dst_params->fPosition.valid = (jack_position_bits_t)ntohl((uint32_t)src_params->fPosition.valid);
01330         dst_params->fPosition.bar = ntohl(src_params->fPosition.bar);
01331         dst_params->fPosition.beat = ntohl(src_params->fPosition.beat);
01332         dst_params->fPosition.tick = ntohl(src_params->fPosition.tick);
01333         dst_params->fPosition.bar_start_tick = ntohll((uint64_t)src_params->fPosition.bar_start_tick);
01334         dst_params->fPosition.beats_per_bar = ntohl((uint32_t)src_params->fPosition.beats_per_bar);
01335         dst_params->fPosition.beat_type = ntohl((uint32_t)src_params->fPosition.beat_type);
01336         dst_params->fPosition.ticks_per_beat = ntohll((uint64_t)src_params->fPosition.ticks_per_beat);
01337         dst_params->fPosition.beats_per_minute = ntohll((uint64_t)src_params->fPosition.beats_per_minute);
01338         dst_params->fPosition.frame_time = ntohll((uint64_t)src_params->fPosition.frame_time);
01339         dst_params->fPosition.next_time = ntohll((uint64_t)src_params->fPosition.next_time);
01340         dst_params->fPosition.bbt_offset = ntohl(src_params->fPosition.bbt_offset);
01341         dst_params->fPosition.audio_frames_per_video_frame = ntohl((uint32_t)src_params->fPosition.audio_frames_per_video_frame);
01342         dst_params->fPosition.video_offset = ntohl(src_params->fPosition.video_offset);
01343         dst_params->fPosition.unique_2 = ntohll(src_params->fPosition.unique_2);
01344     }
01345 
01346 // Utility *******************************************************************************************************
01347 
01348     SERVER_EXPORT int SocketAPIInit()
01349     {
01350 #ifdef WIN32
01351         WORD wVersionRequested = MAKEWORD(2, 2);
01352         WSADATA wsaData;
01353 
01354         if (WSAStartup(wVersionRequested, &wsaData) != 0) {
01355             jack_error("WSAStartup error : %s", strerror(NET_ERROR_CODE));
01356             return -1;
01357         }
01358 
01359         if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
01360             jack_error("Could not find a useable version of Winsock.dll\n");
01361             WSACleanup();
01362             return -1;
01363         }
01364 #endif
01365         return 0;
01366     }
01367 
01368     SERVER_EXPORT int SocketAPIEnd()
01369     {
01370 #ifdef WIN32
01371         return WSACleanup();
01372 #endif
01373         return 0;
01374     }
01375 
01376     SERVER_EXPORT const char* GetTransportState(int transport_state)
01377     {
01378         switch (transport_state)
01379         {
01380             case JackTransportRolling:
01381                 return "rolling";
01382             case JackTransportStarting:
01383                 return "starting";
01384             case JackTransportStopped:
01385                 return "stopped";
01386             case JackTransportNetStarting:
01387                 return "netstarting";
01388         }
01389         return NULL;
01390     }
01391 }