1 //*****************************************************************
2 /*
3   JackTrip: A System for High-Quality Audio Network Performance
4   over the Internet
5 
6   Copyright (c) 2008 Juan-Pablo Caceres, Chris Chafe.
7   SoundWIRE group at CCRMA, Stanford University.
8 
9   Permission is hereby granted, free of charge, to any person
10   obtaining a copy of this software and associated documentation
11   files (the "Software"), to deal in the Software without
12   restriction, including without limitation the rights to use,
13   copy, modify, merge, publish, distribute, sublicense, and/or sell
14   copies of the Software, and to permit persons to whom the
15   Software is furnished to do so, subject to the following
16   conditions:
17 
18   The above copyright notice and this permission notice shall be
19   included in all copies or substantial portions of the Software.
20 
21   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28   OTHER DEALINGS IN THE SOFTWARE.
29 */
30 //*****************************************************************
31 
32 /**
33  * \file AudioInterface.cpp
34  * \author Juan-Pablo Caceres
35  * \date July 2009
36  */
37 
38 #include "AudioInterface.h"
39 #include "JackTrip.h"
40 #include <iostream>
41 #include <cmath>
42 #include <assert.h>
43 
44 using std::cout; using std::endl;
45 
46 //*******************************************************************************
AudioInterface(JackTrip * jacktrip,int NumInChans,int NumOutChans,int NumNetRevChans,audioBitResolutionT AudioBitResolution)47 AudioInterface::AudioInterface(JackTrip* jacktrip,
48                                int NumInChans, int NumOutChans,
49                                #ifdef WAIR // wair
50                                int NumNetRevChans,
51                                #endif // endwhere
52                                audioBitResolutionT AudioBitResolution) :
53     mJackTrip(jacktrip),
54     mNumInChans(NumInChans), mNumOutChans(NumOutChans),
55     #ifdef WAIR // WAIR
56     mNumNetRevChans(NumNetRevChans),
57     #endif // endwhere
58     mAudioBitResolution(AudioBitResolution*8),
59     mBitResolutionMode(AudioBitResolution),
60     mSampleRate(gDefaultSampleRate), mBufferSizeInSamples(gDefaultBufferSizeInSamples),
61     mInputPacket(NULL), mOutputPacket(NULL), mLoopBack(false), mProcessingAudio(false)
62 {
63 #ifndef WAIR
64     //cc
65     // Initialize and assign memory for ProcessPlugins Buffers
66     mInProcessBuffer.resize(mNumInChans);
67     mOutProcessBuffer.resize(mNumOutChans);
68     // Set pointer to NULL
69     for (int i = 0; i < mNumInChans; i++) {
70         mInProcessBuffer[i] = NULL;
71     }
72     for (int i = 0; i < mNumOutChans; i++) {
73         mOutProcessBuffer[i] = NULL;
74     }
75 #else // WAIR
76     int iCnt = (mNumInChans > mNumNetRevChans) ? mNumInChans : mNumNetRevChans;
77     int oCnt = (mNumOutChans > mNumNetRevChans) ? mNumOutChans : mNumNetRevChans;
78     int aCnt = (mNumNetRevChans) ? mNumInChans : 0;
79     for (int i = 0; i < iCnt; i++) {
80         mInProcessBuffer[i] = NULL;
81     }
82     for (int i = 0; i < oCnt; i++) {
83         mOutProcessBuffer[i] = NULL;
84     }
85     for (int i = 0; i < aCnt; i++) {
86         mAPInBuffer[i] = NULL;
87     }
88 #endif // endwhere
89 
90     mInBufCopy.resize(mNumInChans);
91     for (int i=0; i<mNumInChans; i++) {
92       mInBufCopy[i] = new sample_t[MAX_AUDIO_BUFFER_SIZE]; // required for processing audio input
93     }
94 }
95 
96 
97 //*******************************************************************************
~AudioInterface()98 AudioInterface::~AudioInterface()
99 {
100     delete[] mInputPacket;
101     delete[] mOutputPacket;
102 #ifndef WAIR // NOT WAIR:
103     for (int i = 0; i < mNumInChans; i++) {
104         delete[] mInProcessBuffer[i];
105     }
106 
107     for (int i = 0; i < mNumOutChans; i++) {
108         delete[] mOutProcessBuffer[i];
109     }
110 #else // WAIR
111     int iCnt = (mNumInChans > mNumNetRevChans) ? mNumInChans : mNumNetRevChans;
112     int oCnt = (mNumOutChans > mNumNetRevChans) ? mNumOutChans : mNumNetRevChans;
113     int aCnt = (mNumNetRevChans) ? mNumInChans : 0;
114     for (int i = 0; i < iCnt; i++) {
115         delete[] mInProcessBuffer[i];
116     }
117     for (int i = 0; i < oCnt; i++) {
118         delete[] mOutProcessBuffer[i];
119     }
120     for (int i = 0; i < aCnt; i++) {
121         delete[] mAPInBuffer[i];
122     }
123 #endif // endwhere
124 
125     for (int i = 0; i < mProcessPluginsFromNetwork.size(); i++) {
126       delete mProcessPluginsFromNetwork[i];
127     }
128     for (int i = 0; i < mProcessPluginsToNetwork.size(); i++) {
129       delete mProcessPluginsToNetwork[i];
130     }
131     for (int i=0; i<mNumInChans; i++) {
132       delete mInBufCopy[i];
133     }
134 }
135 
136 
137 //*******************************************************************************
setup()138 void AudioInterface::setup()
139 {
140     // Allocate buffer memory to read and write
141     mSizeInBytesPerChannel = getSizeInBytesPerChannel();
142 
143     int size_input  = mSizeInBytesPerChannel * getNumInputChannels();
144     int size_output = mSizeInBytesPerChannel * getNumOutputChannels();
145 #ifdef WAIR // WAIR
146     if(mNumNetRevChans) // else don't change sizes
147     {
148         size_input  = mSizeInBytesPerChannel * mNumNetRevChans;
149         size_output = mSizeInBytesPerChannel * mNumNetRevChans;
150     }
151 #endif // endwhere
152     mInputPacket = new int8_t[size_input];
153     mOutputPacket = new int8_t[size_output];
154 
155     // Initialize and asign memory for ProcessPlugins Buffers
156 #ifdef WAIR // WAIR
157     if(mNumNetRevChans)
158     {
159         mInProcessBuffer.resize(mNumNetRevChans);
160         mOutProcessBuffer.resize(mNumNetRevChans);
161         mAPInBuffer.resize(mNumInChans);
162         mNetInBuffer.resize(mNumNetRevChans);
163     } else // don't change sizes
164 #endif // endwhere
165     {
166         mInProcessBuffer.resize(mNumInChans);
167         mOutProcessBuffer.resize(mNumOutChans);
168     }
169 
170     int nframes = getBufferSizeInSamples();
171 
172 #ifndef WAIR // NOT WAIR:
173     for (int i = 0; i < mNumInChans; i++) {
174         mInProcessBuffer[i] = new sample_t[nframes];
175         // set memory to 0
176         std::memset(mInProcessBuffer[i], 0, sizeof(sample_t) * nframes);
177     }
178     for (int i = 0; i < mNumOutChans; i++) {
179         mOutProcessBuffer[i] = new sample_t[nframes];
180         // set memory to 0
181         std::memset(mOutProcessBuffer[i], 0, sizeof(sample_t) * nframes);
182     }
183 #else // WAIR
184     for (int i = 0; i < ((mNumNetRevChans)?mNumNetRevChans:mNumInChans); i++) {
185         mInProcessBuffer[i] = new sample_t[nframes];
186         // set memory to 0
187         std::memset(mInProcessBuffer[i], 0, sizeof(sample_t) * nframes);
188     }
189     for (int i = 0; i < ((mNumNetRevChans)?mNumNetRevChans:mNumOutChans); i++) {
190         mOutProcessBuffer[i] = new sample_t[nframes];
191         // set memory to 0
192         std::memset(mOutProcessBuffer[i], 0, sizeof(sample_t) * nframes);
193     }
194     for (int i = 0; i < ((mNumNetRevChans)?mNumInChans:0); i++) {
195         mAPInBuffer[i] = new sample_t[nframes];
196         // set memory to 0
197         std::memset(mAPInBuffer[i], 0, sizeof(sample_t) * nframes);
198     }
199     for (int i = 0; i < mNumNetRevChans; i++) {
200         mNetInBuffer[i] = new sample_t[nframes];
201         // set memory to 0
202         std::memset(mNetInBuffer[i], 0, sizeof(sample_t) * nframes);
203     }
204 #endif // endwhere
205 
206 }
207 
208 
209 //*******************************************************************************
getSizeInBytesPerChannel() const210 size_t AudioInterface::getSizeInBytesPerChannel() const
211 {
212     return (getBufferSizeInSamples() * getAudioBitResolution()/8);
213 }
214 
215 
216 //*******************************************************************************
callback(QVarLengthArray<sample_t * > & in_buffer,QVarLengthArray<sample_t * > & out_buffer,unsigned int n_frames)217 void AudioInterface::callback(QVarLengthArray<sample_t*>& in_buffer,
218                               QVarLengthArray<sample_t*>& out_buffer,
219                               unsigned int n_frames)
220 {
221     // Allocate the Process Callback
222     //-------------------------------------------------------------------
223     // 1) First, process incoming packets
224     // ----------------------------------
225 
226 #ifdef WAIR // WAIR
227     //    qDebug() << "--" << mProcessPluginsFromNetwork.size();
228     bool client = (mProcessPluginsFromNetwork.size() == 2);
229 #define COMBDSP 1 // client
230 #define APDSP 0 // client
231 #define DCBDSP 0 // server
232     for (int i = 0; i < mNumNetRevChans; i++) {
233         std::memset(mNetInBuffer[i], 0, sizeof(sample_t) * n_frames);
234     }
235 #endif // endwhere
236 
237     // ==== RECEIVE AUDIO CHANNELS FROM NETWORK ====
238     computeProcessFromNetwork(out_buffer, n_frames);
239     // =============================================
240 
241     // out_buffer is from the network and goes "out" to local audio
242     // hardware via JACK:
243 
244     // mAudioTesterP will be nullptr for hub server's JackTripWorker instances
245     if (mAudioTesterP && mAudioTesterP->getEnabled()) {
246       mAudioTesterP->lookForReturnPulse(out_buffer, n_frames);
247     }
248 
249 #ifdef WAIR // WAIR
250     // nib16 result now in mNetInBuffer
251 #endif // endwhere
252 
253     // 2) Dynamically allocate ProcessPlugin processes
254     // -----------------------------------------------
255     // The processing will be done in order of allocation
256     /// \todo Implement for more than one process plugin, now it just works propertely with one.
257     /// do it chaining outputs to inputs in the buffers. May need a tempo buffer
258 
259 #ifndef WAIR // NOT WAIR:
260     for (int i = 0; i < mProcessPluginsFromNetwork.size(); i++) {
261       ProcessPlugin* p = mProcessPluginsFromNetwork[i];
262       if (p->getInited()) {
263         p->compute(n_frames, out_buffer.data(), out_buffer.data());
264       }
265     }
266 #else // WAIR:
267     for (int i = 0; i < ((mNumNetRevChans)?mNumNetRevChans:mNumOutChans); i++) {
268         std::memset(mOutProcessBuffer[i], 0, sizeof(sample_t) * n_frames);
269     }
270     for (int i = 0; i < ((mNumNetRevChans)?mNumNetRevChans:mNumInChans); i++) {
271         std::memset(mInProcessBuffer[i], 0, sizeof(sample_t) * n_frames);
272         if (mNumNetRevChans)
273         {
274             if (client)
275                 std::memcpy(mInProcessBuffer[i], mNetInBuffer[i], sizeof(sample_t) * n_frames);
276             else
277                 std::memcpy(mOutProcessBuffer[i], mNetInBuffer[i], sizeof(sample_t) * n_frames);
278         }
279     }
280     // nib16 to cib16
281 
282     if (mNumNetRevChans && client) {
283       mProcessPluginsFromNetwork[COMBDSP]->compute(n_frames, mInProcessBuffer.data(), mOutProcessBuffer.data());
284     }
285     // compute cob16
286 #endif // endwhere
287 
288     // 3) Send packets to network:
289     // mAudioTesterP will be nullptr for hub server's JackTripWorker instances:
290     bool audioTesting = (mAudioTesterP && mAudioTesterP->getEnabled());
291     int nop = mProcessPluginsToNetwork.size(); // number of OUTGOING processing modules
292     if (nop>0 || audioTesting) { // cannot modify in_buffer, so make a copy
293       // in_buffer is "in" from local audio hardware via JACK
294       if (mInBufCopy.size() < mNumInChans) { // created in constructor above
295         std::cerr << "*** AudioInterface.cpp: Number of Input Channels changed - insufficient room reserved\n";
296         exit(1);
297       }
298       if (MAX_AUDIO_BUFFER_SIZE < n_frames) { // allocated in constructor above
299         std::cerr << "*** AudioInterface.cpp: n_frames = " << n_frames
300                   << " larger than expected max = " << MAX_AUDIO_BUFFER_SIZE << "\n";
301         exit(1);
302       }
303       for (int i=0; i<mNumInChans; i++) {
304         std::memcpy(mInBufCopy[i], in_buffer[i], sizeof(sample_t) * n_frames);
305       }
306       for (int i = 0; i < nop; i++) {
307         // process all outgoing channels with ProcessPlugins:
308         ProcessPlugin* p = mProcessPluginsToNetwork[i];
309         if (p->getInited()) {
310           p->compute(n_frames, mInBufCopy.data(), mInBufCopy.data());
311         }
312       }
313       if (audioTesting) {
314         mAudioTesterP->writeImpulse(mInBufCopy, n_frames); // writes last channel of mInBufCopy with test impulse
315       }
316       computeProcessToNetwork(mInBufCopy, n_frames);
317     } else { // copy saved if no plugins and no audio testing in progress:
318       computeProcessToNetwork(in_buffer, n_frames); // send processed input audio to network - OUTGOING
319     }
320 
321 #ifdef WAIR // WAIR
322     // aib2 + cob16 to nob16
323 #endif // endwhere
324 
325 #ifdef WAIR // WAIR
326     if (mNumNetRevChans) // else not wair, so skip all this
327     {
328         ///////////////////////////////////////////////////////////////////////////////
329 #define AP
330 #ifndef AP
331         // straight to audio out
332         for (int i = 0; i < mNumOutChans; i++) {
333             std::memset(out_buffer[i], 0, sizeof(sample_t) * n_frames);
334         }
335         for (int i = 0; i < mNumNetRevChans; i++) {
336             sample_t* mix_sample = out_buffer[i%mNumOutChans];
337             sample_t* tmp_sample = mNetInBuffer[i]; //mNetInBuffer
338             for (int j = 0; j < (int)n_frames; j++) {mix_sample[j] += tmp_sample[j];}
339         }                                         // nib6 to aob2
340         ///////////////////////////////////////////////////////////////////////////////
341 #else // AP
342         ///////////////////////////////////////////////////////////////////////////////
343         // output through all-pass cascade
344         // AP2 is 2 channel, mixes inputs to mono, then splits to two parallel AP chains
345         // AP8 is 2 channel, two parallel AP chains
346         for (int i = 0; i < mNumInChans; i++) {
347             std::memset(mAPInBuffer[i], 0, sizeof(sample_t) * n_frames);
348         }
349         for (int i = 0; i < mNumNetRevChans; i++) {
350             sample_t* mix_sample = mAPInBuffer[i%mNumOutChans];
351             sample_t* tmp_sample = mNetInBuffer[i];
352             for (int j = 0; j < n_frames; j++) {mix_sample[j] += tmp_sample[j];}
353         }                                         // nib16 to apib2
354         for (int i = 0; i < mNumOutChans; i++) {
355             std::memset(out_buffer[i], 0, sizeof(sample_t) * n_frames);
356         }
357         mProcessPluginsFromNetwork[APDSP]->compute(n_frames, mAPInBuffer.data(), out_buffer.data());
358         // compute ap2 into aob2
359 
360         //#define ADD_DIRECT
361 #ifdef ADD_DIRECT
362         for (int i = 0; i < mNumInChans; i++) {
363             sample_t* mix_sample = out_buffer[i];
364             sample_t* tmp_sample = in_buffer[i];
365             for (int j = 0; j < n_frames; j++) {mix_sample[j] += tmp_sample[j];}
366         }
367         // add aib2 to aob2
368 #endif // ADD_DIRECT
369 #endif // AP
370         ///////////////////////////////////////////////////////////////////////////////
371     }
372 #endif // endwhere
373 
374     ///************PROTOTYPE FOR CELT**************************
375     ///********************************************************
376     /*
377   CELTMode* mode;
378   int* error;
379   mode = celt_mode_create(48000, 2, 64, error);
380   */
381     //celt_mode_create(48000, 2, 64, NULL);
382     //unsigned char* compressed;
383     //CELTEncoder* celtEncoder;
384     //celt_encode_float(celtEncoder, mInBuffer, NULL, compressed, );
385 
386     ///********************************************************
387     ///********************************************************
388 
389 }
390 
391 //*******************************************************************************
broadcastCallback(QVarLengthArray<sample_t * > & mon_buffer,unsigned int n_frames)392 void AudioInterface::broadcastCallback(QVarLengthArray<sample_t*>& mon_buffer,
393                                                unsigned int n_frames)
394 {
395     /// \todo cast *mInBuffer[i] to the bit resolution
396     // Output Process (from NETWORK to JACK)
397     // ----------------------------------------------------------------
398     // Read Audio buffer from RingBuffer (read from incoming packets)
399     mJackTrip->receiveBroadcastPacket(mOutputPacket);
400         // Extract separate channels to send to Jack
401         for (int i = 0; i < mNumOutChans; i++) {
402             sample_t* tmp_sample = mon_buffer[i]; //sample buffer for channel i
403             for (unsigned int j = 0; j < n_frames; j++) {
404                 // Change the bit resolution on each sample
405                 fromBitToSampleConversion(
406                             // use interleaved channel layout
407                             //&mOutputPacket[(i*mSizeInBytesPerChannel) + (j*mBitResolutionMode)],
408                             &mOutputPacket[(j*mBitResolutionMode*mNumOutChans) + (i*mBitResolutionMode)],
409                         &tmp_sample[j], mBitResolutionMode );
410             }
411         }
412 }
413 
414 //*******************************************************************************
415 // Before sending and reading to Jack, we have to round to the sample resolution
416 // that the program is using. Jack uses 32 bits (gJackBitResolution in globals.h)
417 // by default
computeProcessFromNetwork(QVarLengthArray<sample_t * > & out_buffer,unsigned int n_frames)418 void AudioInterface::computeProcessFromNetwork(QVarLengthArray<sample_t*>& out_buffer,
419                                                unsigned int n_frames)
420 {
421     /// \todo cast *mInBuffer[i] to the bit resolution
422     // Output Process (from NETWORK to JACK)
423     // ----------------------------------------------------------------
424     // Read Audio buffer from RingBuffer (read from incoming packets)
425     mJackTrip->receiveNetworkPacket( mOutputPacket );
426 
427 #ifdef WAIR // WAIR
428     if (mNumNetRevChans)
429         // Extract separate channels
430         for (int i = 0; i < mNumNetRevChans; i++) {
431             sample_t* tmp_sample = mNetInBuffer[i]; //sample buffer for channel i
432             for (unsigned int j = 0; j < n_frames; j++) {
433                 // Change the bit resolution on each sample
434                 fromBitToSampleConversion(
435                             // use interleaved channel layout
436                             //&mOutputPacket[(i*mSizeInBytesPerChannel) + (j*mBitResolutionMode)],
437                             &mOutputPacket[(j*mBitResolutionMode*mNumOutChans) + (i*mBitResolutionMode)],
438                         &tmp_sample[j], mBitResolutionMode );
439             }
440         }
441     else // not wair
442 #endif // endwhere
443 
444         // Extract separate channels to send to Jack
445         for (int i = 0; i < mNumOutChans; i++) {
446             //--------
447             // This should be faster for 32 bits
448             //std::memcpy(mOutBuffer[i], &mOutputPacket[i*mSizeInBytesPerChannel],
449             //         mSizeInBytesPerChannel);
450             //--------
451             sample_t* tmp_sample = out_buffer[i]; //sample buffer for channel i
452             for (unsigned int j = 0; j < n_frames; j++) {
453                 // Change the bit resolution on each sample
454                 fromBitToSampleConversion(
455                             // use interleaved channel layout
456                             //&mOutputPacket[(i*mSizeInBytesPerChannel) + (j*mBitResolutionMode)],
457                             &mOutputPacket[(j*mBitResolutionMode*mNumOutChans) + (i*mBitResolutionMode)],
458                         &tmp_sample[j], mBitResolutionMode );
459             }
460         }
461 }
462 
463 
464 //*******************************************************************************
computeProcessToNetwork(QVarLengthArray<sample_t * > & in_buffer,unsigned int n_frames)465 void AudioInterface::computeProcessToNetwork(QVarLengthArray<sample_t*>& in_buffer,
466                                              unsigned int n_frames)
467 {
468     // Input Process (from JACK to NETWORK)
469     // ----------------------------------------------------------------
470     // Concatenate  all the channels from jack to form packet
471 
472 #ifdef WAIR // WAIR
473     if (mNumNetRevChans)
474         for (int i = 0; i < mNumNetRevChans; i++) {
475             sample_t* tmp_sample = in_buffer[i%mNumInChans]; //sample buffer for channel i
476             sample_t* tmp_process_sample = mOutProcessBuffer[i]; //sample buffer from the output process
477             sample_t tmp_result;
478             for (unsigned int j = 0; j < n_frames; j++) {
479                 // Change the bit resolution on each sample
480                 // Add the input jack buffer to the buffer resulting from the output process
481 #define INGAIN (0.9999) // 0.9999 because 1.0 can saturate the fixed pt rounding on output
482 #define COMBGAIN (1.0)
483                 tmp_result = INGAIN*tmp_sample[j] + COMBGAIN*tmp_process_sample[j];
484                 fromSampleToBitConversion(
485                             &tmp_result,
486                             // use interleaved channel layout
487                             //&mInputPacket[(i*mSizeInBytesPerChannel) + (j*mBitResolutionMode)],
488                             &mInputPacket[(j*mBitResolutionMode*mNumOutChans) + (i*mBitResolutionMode)],
489                         mBitResolutionMode );
490             }
491         }
492     else // not wair
493 #endif // endwhere
494 
495         for (int i = 0; i < mNumInChans; i++) {
496             //--------
497             // This should be faster for 32 bits
498             //std::memcpy(&mInputPacket[i*mSizeInBytesPerChannel], mInBuffer[i],
499             //         mSizeInBytesPerChannel);
500             //--------
501             sample_t* tmp_sample = in_buffer[i]; //sample buffer for channel i
502             sample_t* tmp_process_sample = mOutProcessBuffer[i]; //sample buffer from the output process
503             sample_t tmp_result;
504             for (unsigned int j = 0; j < n_frames; j++) {
505                 // Change the bit resolution on each sample
506                 // Add the input jack buffer to the buffer resulting from the output process
507                 tmp_result = tmp_sample[j] + tmp_process_sample[j];
508                 fromSampleToBitConversion(
509                             &tmp_result,
510                             // use interleaved channel layout
511                             //&mInputPacket[(i*mSizeInBytesPerChannel) + (j*mBitResolutionMode)],
512                             &mInputPacket[(j*mBitResolutionMode*mNumOutChans) + (i*mBitResolutionMode)],
513                         mBitResolutionMode );
514             }
515         }
516     // Send Audio buffer to Network
517     mJackTrip->sendNetworkPacket( mInputPacket );
518 } // /computeProcessToNetwork
519 
520 //*******************************************************************************
521 // This function quantize from 32 bit to a lower bit resolution
522 // 24 bit is not working yet
fromSampleToBitConversion(const sample_t * const input,int8_t * output,const AudioInterface::audioBitResolutionT targetBitResolution)523 void AudioInterface::fromSampleToBitConversion
524 (const sample_t* const input,
525  int8_t* output,
526  const AudioInterface::audioBitResolutionT targetBitResolution)
527 {
528     int8_t tmp_8;
529     uint8_t tmp_u8; // unsigned to quantize the remainder in 24bits
530     int16_t tmp_16;
531     double tmp_sample;
532     sample_t tmp_sample16;
533     sample_t tmp_sample8;
534     switch (targetBitResolution)
535     {
536     case BIT8 :
537         // 8bit integer between -128 to 127
538         tmp_sample = std::max(-127.0, std::min(127.0, std::round( (*input) * 127.0 ))); // 2^7 = 128
539         tmp_8 = static_cast<int8_t>(tmp_sample);
540         std::memcpy(output, &tmp_8, 1); // 8bits = 1 bytes
541         break;
542     case BIT16 :
543         // 16bit integer between -32768 to 32767
544         // original scaling: tmp_sample = floor( (*input) * 32768.0 ); // 2^15 = 32768.0
545         tmp_sample = std::max(-32767.0, std::min(32767.0, std::round( (*input) * 32767.0 ))); // 2^15 = 32768
546         tmp_16 = static_cast<int16_t>(tmp_sample);
547         std::memcpy(output, &tmp_16, 2); // 2 bytes output in Little Endian order (LSB -> smallest address)
548         break;
549     case BIT24 :
550         // To convert to 24 bits, we first quantize the number to 16bit
551         tmp_sample = (*input) * 32768.0; // 2^15 = 32768.0
552         tmp_sample16 = floor(tmp_sample);
553         tmp_16 = static_cast<int16_t>(tmp_sample16);
554 
555         // Then we compute the remainder error, and quantize that part into an 8bit number
556         // Note that this remainder is always positive, so we use an unsigned integer
557         tmp_sample8 = floor ((tmp_sample - tmp_sample16)  //this is a positive number, between 0.0-1.0
558                              * 256.0);
559         tmp_u8 = static_cast<uint8_t>(tmp_sample8);
560 
561         // Finally, we copy the 16bit number in the first 2 bytes,
562         // and the 8bit number in the third bite
563         std::memcpy(output, &tmp_16, 2); // 16bits = 2 bytes
564         std::memcpy(output+2, &tmp_u8, 1); // 8bits = 1 bytes
565         break;
566     case BIT32 :
567         tmp_sample = *input;
568         // not necessary yet:
569         // tmp_sample = std::max(-1.0, std::min(1.0, tmp_sample));
570         std::memcpy(output, &tmp_sample, 4); // 32bit = 4 bytes
571         break;
572     }
573 }
574 
575 
576 //*******************************************************************************
fromBitToSampleConversion(const int8_t * const input,sample_t * output,const AudioInterface::audioBitResolutionT sourceBitResolution)577 void AudioInterface::fromBitToSampleConversion
578 (const int8_t* const input,
579  sample_t* output,
580  const AudioInterface::audioBitResolutionT sourceBitResolution)
581 {
582     int8_t tmp_8;
583     uint8_t tmp_u8;
584     int16_t tmp_16;
585     sample_t tmp_sample;
586     sample_t tmp_sample16;
587     sample_t tmp_sample8;
588     switch (sourceBitResolution)
589     {
590     case BIT8 :
591         tmp_8 = *input;
592         tmp_sample = static_cast<sample_t>(tmp_8) / 128.0;
593         std::memcpy(output, &tmp_sample, 4); // 4 bytes
594         break;
595     case BIT16 :
596         tmp_16 = *( reinterpret_cast<const int16_t*>(input) ); // *((int16_t*) input);
597         tmp_sample = static_cast<sample_t>(tmp_16) / 32768.0;
598         std::memcpy(output, &tmp_sample, 4); // 4 bytes
599         break;
600     case BIT24 :
601         // We first extract the 16bit and 8bit number from the 3 bytes
602         tmp_16 = *( reinterpret_cast<const int16_t*>(input) );
603         tmp_u8 = *( reinterpret_cast<const uint8_t*>(input+2) );
604 
605         // Then we recover the number
606         tmp_sample16 = static_cast<sample_t>(tmp_16);
607         tmp_sample8 = static_cast<sample_t>(tmp_u8) / 256.0;
608         tmp_sample =  (tmp_sample16 +  tmp_sample8) / 32768.0;
609         std::memcpy(output, &tmp_sample, 4); // 4 bytes
610         break;
611     case BIT32 :
612         std::memcpy(output, input, 4); // 4 bytes
613         break;
614     }
615 }
616 
617 
618 //*******************************************************************************
appendProcessPluginToNetwork(ProcessPlugin * plugin)619 void AudioInterface::appendProcessPluginToNetwork(ProcessPlugin* plugin)
620 {
621   if (not plugin) { return; }
622   int nTestChans = (mAudioTesterP && mAudioTesterP->getEnabled()) ? 1 : 0;
623   int nPluginChans = mNumInChans - nTestChans;
624   assert(nTestChans==0 || (mAudioTesterP->getSendChannel() == mNumInChans-1));
625   if (plugin->getNumInputs() < nPluginChans) {
626     std::cerr << "*** AudioInterface.cpp: appendProcessPluginToNetwork: ProcessPlugin "
627               << typeid(plugin).name() << " REJECTED due to having "
628               << plugin->getNumInputs() << " inputs, while the audio to JACK needs "
629               << nPluginChans << " inputs\n";
630     return;
631   }
632   mProcessPluginsToNetwork.append(plugin);
633 }
634 
appendProcessPluginFromNetwork(ProcessPlugin * plugin)635 void AudioInterface::appendProcessPluginFromNetwork(ProcessPlugin* plugin)
636 {
637   if (not plugin) { return; }
638   int nTestChans = (mAudioTesterP && mAudioTesterP->getEnabled()) ? 1 : 0;
639   int nPluginChans = mNumOutChans - nTestChans;
640   assert(nTestChans==0 || (mAudioTesterP->getSendChannel() == mNumOutChans-1));
641   if (plugin->getNumOutputs() > nPluginChans) {
642     std::cerr << "*** AudioInterface.cpp: appendProcessPluginFromNetwork: ProcessPlugin "
643               << typeid(plugin).name() << " REJECTED due to having "
644               << plugin->getNumOutputs() << " inputs, while the JACK audio output requires "
645               << nPluginChans << " outputs\n";
646     return;
647   }
648   mProcessPluginsFromNetwork.append(plugin);
649 }
650 
initPlugins()651 void AudioInterface::initPlugins()
652 {
653   int nPlugins = mProcessPluginsFromNetwork.size() + mProcessPluginsToNetwork.size();
654   if (nPlugins > 0) {
655     std::cout << "Initializing Faust plugins (have " << nPlugins
656               << ") at sampling rate " << mSampleRate << "\n";
657     for (ProcessPlugin* plugin : mProcessPluginsFromNetwork) {
658       plugin->init(mSampleRate);
659     }
660     for (ProcessPlugin* plugin : mProcessPluginsToNetwork) {
661       plugin->init(mSampleRate);
662     }
663   }
664 }
665 
666 //*******************************************************************************
getSampleRateType() const667 AudioInterface::samplingRateT AudioInterface::getSampleRateType() const
668 {
669     int32_t rate = getSampleRate();
670 
671     if      ( 100 > qAbs(rate - 22050) ) {
672         return AudioInterface::SR22; }
673     else if ( 100 > qAbs(rate - 32000) ) {
674         return AudioInterface::SR32; }
675     else if ( 100 > qAbs(rate - 44100) ) {
676         return AudioInterface::SR44; }
677     else if ( 100 > qAbs(rate - 48000) ) {
678         return AudioInterface::SR48; }
679     else if ( 100 > qAbs(rate - 88200) ) {
680         return AudioInterface::SR88; }
681     else if ( 100 > qAbs(rate - 96000) ) {
682         return AudioInterface::SR96; }
683     else if ( 100 > qAbs(rate - 19200) ) {
684         return AudioInterface::SR192; }
685 
686     return AudioInterface::UNDEF;
687 }
688 
689 //*******************************************************************************
getSampleRateFromType(samplingRateT rate_type)690 int AudioInterface::getSampleRateFromType(samplingRateT rate_type)
691 {
692     int sample_rate = 0;
693     switch (rate_type)
694     {
695     case SR22 :
696         sample_rate = 22050;
697         return sample_rate;
698         break;
699     case SR32 :
700         sample_rate = 32000;
701         return sample_rate;
702         break;
703     case SR44 :
704         sample_rate = 44100;
705         return sample_rate;
706         break;
707     case SR48 :
708         sample_rate = 48000;
709         return sample_rate;
710         break;
711     case SR88 :
712         sample_rate = 88200;
713         return sample_rate;
714         break;
715     case SR96 :
716         sample_rate = 96000;
717         return sample_rate;
718         break;
719     case SR192 :
720         sample_rate = 192000;
721         return sample_rate;
722         break;
723     default:
724         return sample_rate;
725         break;
726     }
727 
728     return sample_rate;
729 }
730