| @@ -1,33 +1,32 @@ | |||
| --------------------------- | |||
| Contributors | |||
| --------------------------- | |||
| Dmitry Baikov | |||
| Gabriel M. Beddingfield | |||
| Steven Chamberlain | |||
| Thom Johansen | |||
| Thibault LeMeur | |||
| Tom Szilagyi | |||
| Andrzej Szombierski | |||
| Kjetil S.Matheussen | |||
| Pieter Palmers | |||
| Tim Blechmann | |||
| Marc-Olivier Barre | |||
| Nedko Arnaudov | |||
| Fernando Lopez-Lezcano | |||
| Romain Moret | |||
| Florian Faber | |||
| Michael Voigt | |||
| Torben Hohn | |||
| Paul Davis | |||
| Peter L Jones | |||
| Devin Anderson | |||
| Josh Green | |||
| Mario Lang | |||
| --------------------------- | |||
| Contributors | |||
| --------------------------- | |||
| Dmitry Baikov | |||
| Gabriel M. Beddingfield | |||
| Steven Chamberlain | |||
| Thom Johansen | |||
| Thibault LeMeur | |||
| Tom Szilagyi | |||
| Andrzej Szombierski | |||
| Kjetil S.Matheussen | |||
| Pieter Palmers | |||
| Tim Blechmann | |||
| Marc-Olivier Barre | |||
| Nedko Arnaudov | |||
| Fernando Lopez-Lezcano | |||
| Romain Moret | |||
| Florian Faber | |||
| Michael Voigt | |||
| Torben Hohn | |||
| Paul Davis | |||
| Peter L Jones | |||
| Devin Anderson | |||
| Josh Green | |||
| Mario Lang | |||
| Arnold Krille | |||
| Jan Engelhardt | |||
| Adrian Knoth | |||
| David Garcia Garzon | |||
| Valerio Pilo | |||
| --------------------------- | |||
| @@ -107,7 +106,7 @@ Valerio Pilo | |||
| * jack_client_has_session_callback implementation. | |||
| * Fix jdelay for new latency API. | |||
| * Check requested buffer size and limit to 1..8192 - avoids weird behaviour caused by jack_bufsize foobar. | |||
| * Check requested buffer size and limit to 1..8192 - avoids wierd behaviour caused by jack_bufsize foobar. | |||
| * jack_port_type_get_buffer_size implementation. | |||
| * Stop using alloca and allocate buffer on the heap for alsa_io. | |||
| * Rename jdelay to jack_iodelay as per Fons' request. | |||
| @@ -1770,4 +1769,4 @@ Valerio Pilo | |||
| 2006-09-03 Stephane Letz <letz@grame.fr> | |||
| * First import of version 0.58 base code | |||
| * First import of version 0.58 base code | |||
| @@ -17,9 +17,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #ifdef __APPLE__ | |||
| #include <TargetConditionals.h> | |||
| #endif | |||
| #include "JackAudioAdapter.h" | |||
| #ifndef MY_TARGET_OS_IPHONE | |||
| #include "JackLibSampleRateResampler.h" | |||
| #include "JackTime.h" | |||
| #endif | |||
| #include "JackTime.h" | |||
| #include <stdio.h> | |||
| namespace Jack | |||
| @@ -66,11 +72,11 @@ namespace Jack | |||
| fprintf(file, buffer); | |||
| sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Ringbuffer error with timing correction\" with lines"); | |||
| fprintf(file, buffer); | |||
| fprintf(file, "\n unset multiplot\n"); | |||
| fprintf(file, "\n unset multiplot\n"); | |||
| fprintf(file, "set output 'AdapterTiming1.svg\n"); | |||
| fprintf(file, "set terminal svg\n"); | |||
| fprintf(file, "set multiplot\n"); | |||
| fprintf(file, "set grid\n"); | |||
| fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" | |||
| @@ -84,9 +90,9 @@ namespace Jack | |||
| fprintf(file, buffer); | |||
| fprintf(file, "unset multiplot\n"); | |||
| fprintf(file, "unset output\n"); | |||
| fclose(file); | |||
| // Adapter timing 2 | |||
| file = fopen("AdapterTiming2.plot", "w"); | |||
| fprintf(file, "set multiplot\n"); | |||
| @@ -100,11 +106,11 @@ namespace Jack | |||
| fprintf(file, buffer); | |||
| sprintf(buffer, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines"); | |||
| fprintf(file, buffer); | |||
| fprintf(file, "\n unset multiplot\n"); | |||
| fprintf(file, "\n unset multiplot\n"); | |||
| fprintf(file, "set output 'AdapterTiming2.svg\n"); | |||
| fprintf(file, "set terminal svg\n"); | |||
| fprintf(file, "set multiplot\n"); | |||
| fprintf(file, "set grid\n"); | |||
| fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" | |||
| @@ -118,7 +124,7 @@ namespace Jack | |||
| fprintf(file, buffer); | |||
| fprintf(file, "unset multiplot\n"); | |||
| fprintf(file, "unset output\n"); | |||
| fclose(file); | |||
| // Adapter timing 3 | |||
| @@ -134,11 +140,11 @@ namespace Jack | |||
| fprintf(file, buffer); | |||
| sprintf(buffer, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines"); | |||
| fprintf(file, buffer); | |||
| fprintf(file, "\n unset multiplot\n"); | |||
| fprintf(file, "\n unset multiplot\n"); | |||
| fprintf(file, "set output 'AdapterTiming3.svg\n"); | |||
| fprintf(file, "set terminal svg\n"); | |||
| fprintf(file, "set multiplot\n"); | |||
| fprintf(file, "set grid\n"); | |||
| fprintf(file, "set title \"Audio adapter timing: host [rate = %.1f kHz buffer = %d frames] adapter [rate = %.1f kHz buffer = %d frames] \"\n" | |||
| @@ -152,7 +158,7 @@ namespace Jack | |||
| fprintf(file, buffer); | |||
| fprintf(file, "unset multiplot\n"); | |||
| fprintf(file, "unset output\n"); | |||
| fclose(file); | |||
| } | |||
| @@ -162,47 +168,51 @@ namespace Jack | |||
| { | |||
| fRingbufferCurSize *= 2; | |||
| } | |||
| void JackAudioAdapterInterface::AdaptRingBufferSize() | |||
| { | |||
| if (fHostBufferSize > fAdaptedBufferSize) | |||
| fRingbufferCurSize = 4 * fHostBufferSize; | |||
| else | |||
| else | |||
| fRingbufferCurSize = 4 * fAdaptedBufferSize; | |||
| } | |||
| void JackAudioAdapterInterface::ResetRingBuffers() | |||
| { | |||
| if (fRingbufferCurSize > DEFAULT_RB_SIZE) | |||
| if (fRingbufferCurSize > DEFAULT_RB_SIZE) | |||
| fRingbufferCurSize = DEFAULT_RB_SIZE; | |||
| for (int i = 0; i < fCaptureChannels; i++) | |||
| fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); | |||
| for (int i = 0; i < fPlaybackChannels; i++) | |||
| fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); | |||
| } | |||
| void JackAudioAdapterInterface::Reset() | |||
| { | |||
| ResetRingBuffers(); | |||
| fRunning = false; | |||
| } | |||
| #ifdef MY_TARGET_OS_IPHONE | |||
| void JackAudioAdapterInterface::Create() | |||
| {} | |||
| #else | |||
| void JackAudioAdapterInterface::Create() | |||
| { | |||
| //ringbuffers | |||
| fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; | |||
| fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; | |||
| if (fAdaptative) { | |||
| AdaptRingBufferSize(); | |||
| jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize); | |||
| } else { | |||
| if (fRingbufferCurSize > DEFAULT_RB_SIZE) | |||
| if (fRingbufferCurSize > DEFAULT_RB_SIZE) | |||
| fRingbufferCurSize = DEFAULT_RB_SIZE; | |||
| jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize); | |||
| } | |||
| for (int i = 0; i < fCaptureChannels; i++ ) { | |||
| fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fQuality); | |||
| fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); | |||
| @@ -211,12 +221,13 @@ namespace Jack | |||
| fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fQuality); | |||
| fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); | |||
| } | |||
| if (fCaptureChannels > 0) | |||
| jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); | |||
| if (fPlaybackChannels > 0) | |||
| jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace()); | |||
| } | |||
| #endif | |||
| void JackAudioAdapterInterface::Destroy() | |||
| { | |||
| @@ -228,39 +239,45 @@ namespace Jack | |||
| delete[] fCaptureRingBuffer; | |||
| delete[] fPlaybackRingBuffer; | |||
| } | |||
| int JackAudioAdapterInterface::PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames) | |||
| { | |||
| bool failure = false; | |||
| fRunning = true; | |||
| // Finer estimation of the position in the ringbuffer | |||
| int delta_frames = (fPullAndPushTime > 0) ? (int)((float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f) : 0; | |||
| double ratio = 1; | |||
| // TODO : done like this just to avoid crash when input only or output only... | |||
| if (fCaptureChannels > 0) | |||
| ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames); | |||
| else if (fPlaybackChannels > 0) | |||
| ratio = fPIControler.GetRatio(fPlaybackRingBuffer[0]->GetError() - delta_frames); | |||
| #ifdef JACK_MONITOR | |||
| if (fCaptureRingBuffer[0] != NULL) | |||
| if (fCaptureRingBuffer && fCaptureRingBuffer[0] != NULL) | |||
| fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace()); | |||
| #endif | |||
| // Push/pull from ringbuffer | |||
| for (int i = 0; i < fCaptureChannels; i++) { | |||
| fCaptureRingBuffer[i]->SetRatio(ratio); | |||
| if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], frames) < frames) | |||
| failure = true; | |||
| if (inputBuffer[i]) { | |||
| if (fCaptureRingBuffer[i]->WriteResample(inputBuffer[i], frames) < frames) { | |||
| failure = true; | |||
| } | |||
| } | |||
| } | |||
| for (int i = 0; i < fPlaybackChannels; i++) { | |||
| fPlaybackRingBuffer[i]->SetRatio(1/ratio); | |||
| if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames) | |||
| failure = true; | |||
| if (outputBuffer[i]) { | |||
| if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames) { | |||
| failure = true; | |||
| } | |||
| } | |||
| } | |||
| // Reset all ringbuffers in case of failure | |||
| if (failure) { | |||
| @@ -276,26 +293,32 @@ namespace Jack | |||
| } | |||
| } | |||
| int JackAudioAdapterInterface::PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames) | |||
| int JackAudioAdapterInterface::PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames) | |||
| { | |||
| fPullAndPushTime = GetMicroSeconds(); | |||
| if (!fRunning) | |||
| return 0; | |||
| int res = 0; | |||
| // Push/pull from ringbuffer | |||
| for (int i = 0; i < fCaptureChannels; i++) { | |||
| if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) | |||
| res = -1; | |||
| if (inputBuffer[i]) { | |||
| if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) { | |||
| res = -1; | |||
| } | |||
| } | |||
| } | |||
| for (int i = 0; i < fPlaybackChannels; i++) { | |||
| if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames) | |||
| res = -1; | |||
| if (outputBuffer[i]) { | |||
| if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames) { | |||
| res = -1; | |||
| } | |||
| } | |||
| } | |||
| return res; | |||
| } | |||
| } // namespace | |||
| @@ -102,7 +102,7 @@ namespace Jack | |||
| public: | |||
| JackAudioAdapterInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ): | |||
| JackAudioAdapterInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_nframes_t ring_buffer_size = DEFAULT_ADAPTATIVE_SIZE): | |||
| fCaptureChannels ( 0 ), | |||
| fPlaybackChannels ( 0 ), | |||
| fHostBufferSize ( buffer_size ), | |||
| @@ -112,19 +112,37 @@ namespace Jack | |||
| fPIControler(sample_rate / sample_rate, 256), | |||
| fCaptureRingBuffer(NULL), fPlaybackRingBuffer(NULL), | |||
| fQuality(0), | |||
| fRingbufferCurSize(DEFAULT_ADAPTATIVE_SIZE), | |||
| fRingbufferCurSize(ring_buffer_size), | |||
| fPullAndPushTime(0), | |||
| fRunning(false), | |||
| fAdaptative(true) | |||
| {} | |||
| JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, | |||
| jack_nframes_t host_sample_rate, | |||
| jack_nframes_t adapted_buffer_size, | |||
| jack_nframes_t adapted_sample_rate, | |||
| jack_nframes_t ring_buffer_size = DEFAULT_ADAPTATIVE_SIZE ) : | |||
| fCaptureChannels ( 0 ), | |||
| fPlaybackChannels ( 0 ), | |||
| fHostBufferSize ( host_buffer_size ), | |||
| fHostSampleRate ( host_sample_rate ), | |||
| fAdaptedBufferSize ( adapted_buffer_size), | |||
| fAdaptedSampleRate ( adapted_sample_rate ), | |||
| fPIControler(host_sample_rate / host_sample_rate, 256), | |||
| fQuality(0), | |||
| fRingbufferCurSize(ring_buffer_size), | |||
| fPullAndPushTime(0), | |||
| fRunning(false), | |||
| fAdaptative(true) | |||
| {} | |||
| virtual ~JackAudioAdapterInterface() | |||
| {} | |||
| virtual void Reset(); | |||
| void Create(); | |||
| void Destroy(); | |||
| virtual void Create(); | |||
| virtual void Destroy(); | |||
| virtual int Open() | |||
| { | |||
| @@ -194,18 +212,18 @@ namespace Jack | |||
| int GetInputs() | |||
| { | |||
| jack_log ( "JackAudioAdapterInterface::GetInputs %d", fCaptureChannels ); | |||
| //jack_log("JackAudioAdapterInterface::GetInputs %d", fCaptureChannels); | |||
| return fCaptureChannels; | |||
| } | |||
| int GetOutputs() | |||
| { | |||
| jack_log ( "JackAudioAdapterInterface::GetOutputs %d", fPlaybackChannels ); | |||
| //jack_log ("JackAudioAdapterInterface::GetOutputs %d", fPlaybackChannels); | |||
| return fPlaybackChannels; | |||
| } | |||
| int PushAndPull(jack_default_audio_sample_t** inputBuffer, jack_default_audio_sample_t** outputBuffer, unsigned int inNumberFrames); | |||
| int PullAndPush(jack_default_audio_sample_t** inputBuffer, jack_default_audio_sample_t** outputBuffer, unsigned int inNumberFrames); | |||
| int PushAndPull(jack_default_audio_sample_t** inputBuffer, jack_default_audio_sample_t** outputBuffer, unsigned int frames); | |||
| int PullAndPush(jack_default_audio_sample_t** inputBuffer, jack_default_audio_sample_t** outputBuffer, unsigned int frames); | |||
| }; | |||
| @@ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU Lesser General Public License for more details. | |||
| You should have received a copy of the GNU Lesser General Public License | |||
| along with this program; if not, write to the Free Software | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| @@ -34,7 +34,7 @@ namespace Jack | |||
| JackEngineProfiling::JackEngineProfiling():fAudioCycle(0),fMeasuredClient(0) | |||
| { | |||
| jack_info("Engine profiling activated, beware %ld MBytes are needed to record profiling points...", sizeof(fProfileTable) / (1024 * 1024)); | |||
| // Force memory page in | |||
| memset(fProfileTable, 0, sizeof(fProfileTable)); | |||
| } | |||
| @@ -47,32 +47,32 @@ JackEngineProfiling::~JackEngineProfiling() | |||
| if (!fStream.is_open()) { | |||
| jack_error("JackEngineProfiling::Save cannot open JackEngineProfiling.log file"); | |||
| } else { | |||
| // For each measured point | |||
| for (int i = 2; i < TIME_POINTS; i++) { | |||
| // Driver timing values | |||
| long d1 = long(fProfileTable[i].fCurCycleBegin - fProfileTable[i - 1].fCurCycleBegin); | |||
| long d2 = long(fProfileTable[i].fPrevCycleEnd - fProfileTable[i - 1].fCurCycleBegin); | |||
| if (d1 <= 0 || fProfileTable[i].fAudioCycle <= 0) | |||
| continue; // Skip non valid cycles | |||
| // Print driver delta and end cycle | |||
| fStream << d1 << "\t" << d2 << "\t"; | |||
| // For each measured client | |||
| for (unsigned int j = 0; j < fMeasuredClient; j++) { | |||
| for (unsigned int j = 0; j < fMeasuredClient; j++) { | |||
| int ref = fIntervalTable[j].fRefNum; | |||
| // Is valid client cycle | |||
| if (fProfileTable[i].fClientTable[ref].fStatus != NotTriggered) { | |||
| // Is valid client cycle | |||
| if (fProfileTable[i].fClientTable[ref].fStatus != NotTriggered) { | |||
| long d5 = long(fProfileTable[i].fClientTable[ref].fSignaledAt - fProfileTable[i - 1].fCurCycleBegin); | |||
| long d6 = long(fProfileTable[i].fClientTable[ref].fAwakeAt - fProfileTable[i - 1].fCurCycleBegin); | |||
| long d7 = long(fProfileTable[i].fClientTable[ref].fFinishedAt - fProfileTable[i - 1].fCurCycleBegin); | |||
| fStream << ref << "\t" ; | |||
| fStream << ((d5 > 0) ? d5 : 0) << "\t"; | |||
| fStream << ((d6 > 0) ? d6 : 0) << "\t" ; | |||
| @@ -80,57 +80,57 @@ JackEngineProfiling::~JackEngineProfiling() | |||
| fStream << ((d6 > 0 && d5 > 0) ? (d6 - d5) : 0) << "\t" ; | |||
| fStream << ((d7 > 0 && d6 > 0) ? (d7 - d6) : 0) << "\t" ; | |||
| fStream << fProfileTable[i].fClientTable[ref].fStatus << "\t" ;; | |||
| } else { // Print tabs | |||
| fStream << "\t \t \t \t \t \t \t"; | |||
| } | |||
| } | |||
| // Terminate line | |||
| fStream << std::endl; | |||
| } | |||
| } | |||
| // Driver period | |||
| std::ofstream fStream1("Timing1.plot", std::ios_base::ate); | |||
| if (!fStream1.is_open()) { | |||
| jack_error("JackEngineProfiling::Save cannot open Timing1.plot file"); | |||
| } else { | |||
| fStream1 << "set grid\n"; | |||
| fStream1 << "set title \"Audio driver timing\"\n"; | |||
| fStream1 << "set xlabel \"audio cycles\"\n"; | |||
| fStream1 << "set ylabel \"usec\"\n"; | |||
| fStream1 << "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"; | |||
| fStream1 << "set output 'Timing1.svg\n"; | |||
| fStream1 << "set terminal svg\n"; | |||
| fStream1 << "set grid\n"; | |||
| fStream1 << "set title \"Audio driver timing\"\n"; | |||
| fStream1 << "set xlabel \"audio cycles\"\n"; | |||
| fStream1 << "set ylabel \"usec\"\n"; | |||
| fStream1 << "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"; | |||
| fStream1 << "unset output\n"; | |||
| fStream1 << "unset output\n"; | |||
| } | |||
| // Driver end date | |||
| std::ofstream fStream2("Timing2.plot", std::ios_base::ate); | |||
| if (!fStream2.is_open()) { | |||
| jack_error("JackEngineProfiling::Save cannot open Timing2.plot file"); | |||
| } else { | |||
| fStream2 << "set grid\n"; | |||
| fStream2 << "set title \"Driver end date\"\n"; | |||
| fStream2 << "set xlabel \"audio cycles\"\n"; | |||
| fStream2 << "set ylabel \"usec\"\n"; | |||
| fStream2 << "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"; | |||
| fStream2 << "set output 'Timing2.svg\n"; | |||
| fStream2 << "set terminal svg\n"; | |||
| fStream2 << "set grid\n"; | |||
| fStream2 << "set title \"Driver end date\"\n"; | |||
| fStream2 << "set xlabel \"audio cycles\"\n"; | |||
| @@ -138,15 +138,15 @@ JackEngineProfiling::~JackEngineProfiling() | |||
| fStream2 << "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"; | |||
| fStream2 << "unset output\n"; | |||
| } | |||
| // Clients end date | |||
| if (fMeasuredClient > 0) { | |||
| std::ofstream fStream3("Timing3.plot", std::ios_base::ate); | |||
| if (!fStream3.is_open()) { | |||
| jack_error("JackEngineProfiling::Save cannot open Timing3.plot file"); | |||
| } else { | |||
| fStream3 << "set multiplot\n"; | |||
| fStream3 << "set grid\n"; | |||
| fStream3 << "set title \"Clients end date\"\n"; | |||
| @@ -170,11 +170,11 @@ JackEngineProfiling::~JackEngineProfiling() | |||
| fStream3 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) - 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; | |||
| } | |||
| } | |||
| fStream3 << "\n unset multiplot\n"; | |||
| fStream3 << "\n unset multiplot\n"; | |||
| fStream3 << "set output 'Timing3.svg\n"; | |||
| fStream3 << "set terminal svg\n"; | |||
| fStream3 << "set multiplot\n"; | |||
| fStream3 << "set grid\n"; | |||
| fStream3 << "set title \"Clients end date\"\n"; | |||
| @@ -206,11 +206,11 @@ JackEngineProfiling::~JackEngineProfiling() | |||
| // Clients scheduling | |||
| if (fMeasuredClient > 0) { | |||
| std::ofstream fStream4("Timing4.plot", std::ios_base::ate); | |||
| if (!fStream4.is_open()) { | |||
| jack_error("JackEngineProfiling::Save cannot open Timing4.plot file"); | |||
| } else { | |||
| fStream4 << "set multiplot\n"; | |||
| fStream4 << "set grid\n"; | |||
| fStream4 << "set title \"Clients scheduling latency\"\n"; | |||
| @@ -224,11 +224,11 @@ JackEngineProfiling::~JackEngineProfiling() | |||
| fStream4 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) << " title \"" << fIntervalTable[i].fName << "\" with lines,"; | |||
| } | |||
| } | |||
| fStream4 << "\n unset multiplot\n"; | |||
| fStream4 << "\n unset multiplot\n"; | |||
| fStream4 << "set output 'Timing4.svg\n"; | |||
| fStream4 << "set terminal svg\n"; | |||
| fStream4 << "set multiplot\n"; | |||
| fStream4 << "set grid\n"; | |||
| fStream4 << "set title \"Clients scheduling latency\"\n"; | |||
| @@ -246,7 +246,7 @@ JackEngineProfiling::~JackEngineProfiling() | |||
| fStream4 << "unset output\n"; | |||
| } | |||
| } | |||
| // Clients duration | |||
| if (fMeasuredClient > 0) { | |||
| std::ofstream fStream5("Timing5.plot", std::ios_base::ate); | |||
| @@ -254,7 +254,7 @@ JackEngineProfiling::~JackEngineProfiling() | |||
| if (!fStream5.is_open()) { | |||
| jack_error("JackEngineProfiling::Save cannot open Timing5.plot file"); | |||
| } else { | |||
| fStream5 << "set multiplot\n"; | |||
| fStream5 << "set grid\n"; | |||
| fStream5 << "set title \"Clients duration\"\n"; | |||
| @@ -268,11 +268,11 @@ JackEngineProfiling::~JackEngineProfiling() | |||
| fStream5 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) + 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; | |||
| } | |||
| } | |||
| fStream5 << "\n unset multiplot\n"; | |||
| fStream5 << "\n unset multiplot\n"; | |||
| fStream5 << "set output 'Timing5.svg\n"; | |||
| fStream5 << "set terminal svg\n"; | |||
| fStream5 << "set multiplot\n"; | |||
| fStream5 << "set grid\n"; | |||
| fStream5 << "set title \"Clients duration\"\n"; | |||
| @@ -290,7 +290,7 @@ JackEngineProfiling::~JackEngineProfiling() | |||
| fStream5 << "unset output\n"; | |||
| } | |||
| } | |||
| std::ofstream fStream6("Timings.html", std::ios_base::ate); | |||
| if (!fStream6.is_open()) { | |||
| jack_error("JackEngineProfiling::Save cannot open Timings.html file"); | |||
| @@ -315,8 +315,8 @@ JackEngineProfiling::~JackEngineProfiling() | |||
| fStream6 << " <div class='center'><object class='center' type='image/svg+xml' data='Timing5.svg'>Timing5</object></div>"; | |||
| fStream6 << " </body>\n"; | |||
| fStream6 << "</html>\n"; | |||
| } | |||
| } | |||
| std::ofstream fStream7("generate_timings", std::ios_base::ate); | |||
| if (!fStream7.is_open()) { | |||
| jack_error("JackEngineProfiling::Save cannot open generate_timings file"); | |||
| @@ -326,7 +326,7 @@ JackEngineProfiling::~JackEngineProfiling() | |||
| fStream7 << "gnuplot -persist Timing3.plot\n"; | |||
| fStream7 << "gnuplot -persist Timing4.plot\n"; | |||
| fStream7 << "gnuplot -persist Timing5.plot\n"; | |||
| } | |||
| } | |||
| } | |||
| bool JackEngineProfiling::CheckClient(const char* name, int cur_point) | |||
| @@ -340,14 +340,14 @@ bool JackEngineProfiling::CheckClient(const char* name, int cur_point) | |||
| return false; | |||
| } | |||
| void JackEngineProfiling::Profile(JackClientInterface** table, | |||
| JackGraphManager* manager, | |||
| void JackEngineProfiling::Profile(JackClientInterface** table, | |||
| JackGraphManager* manager, | |||
| jack_time_t period_usecs, | |||
| jack_time_t cur_cycle_begin, | |||
| jack_time_t cur_cycle_begin, | |||
| jack_time_t prev_cycle_end) | |||
| { | |||
| fAudioCycle = (fAudioCycle + 1) % TIME_POINTS; | |||
| // Keeps cycle data | |||
| fProfileTable[fAudioCycle].fPeriodUsecs = period_usecs; | |||
| fProfileTable[fAudioCycle].fCurCycleBegin = cur_cycle_begin; | |||
| @@ -358,7 +358,7 @@ void JackEngineProfiling::Profile(JackClientInterface** table, | |||
| JackClientInterface* client = table[i]; | |||
| JackClientTiming* timing = manager->GetClientTiming(i); | |||
| if (client && client->GetClientControl()->fActive && client->GetClientControl()->fCallback[kRealTimeCallback]) { | |||
| if (!CheckClient(client->GetClientControl()->fName, fAudioCycle)) { | |||
| // Keep new measured client | |||
| fIntervalTable[fMeasuredClient].fRefNum = i; | |||
| @@ -380,5 +380,5 @@ JackTimingMeasure* JackEngineProfiling::GetCurMeasure() | |||
| { | |||
| return &fProfileTable[fAudioCycle]; | |||
| } | |||
| } // end of namespace | |||
| @@ -20,33 +20,41 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| #ifndef __JackFilters__ | |||
| #define __JackFilters__ | |||
| #ifdef __APPLE__ | |||
| #include <TargetConditionals.h> | |||
| #endif | |||
| #include "jack.h" | |||
| #ifndef MY_TARGET_OS_IPHONE | |||
| #include "JackAtomicState.h" | |||
| #endif | |||
| #include <math.h> | |||
| #include <stdlib.h> | |||
| namespace Jack | |||
| { | |||
| #ifndef TARGET_OS_IPHONE | |||
| #define MAX_SIZE 64 | |||
| struct JackFilter | |||
| struct JackFilter | |||
| { | |||
| jack_time_t fTable[MAX_SIZE]; | |||
| JackFilter() | |||
| { | |||
| for (int i = 0; i < MAX_SIZE; i++) | |||
| fTable[i] = 0; | |||
| } | |||
| void AddValue(jack_time_t val) | |||
| { | |||
| memcpy(&fTable[1], &fTable[0], sizeof(jack_time_t) * (MAX_SIZE - 1)); | |||
| fTable[0] = val; | |||
| } | |||
| jack_time_t GetVal() | |||
| { | |||
| jack_time_t mean = 0; | |||
| @@ -54,14 +62,14 @@ namespace Jack | |||
| mean += fTable[i]; | |||
| return mean / MAX_SIZE; | |||
| } | |||
| } POST_PACKED_STRUCTURE; | |||
| class JackDelayLockedLoop | |||
| { | |||
| private: | |||
| jack_nframes_t fFrames; | |||
| jack_time_t fCurrentWakeup; | |||
| jack_time_t fCurrentCallback; | |||
| @@ -72,17 +80,17 @@ namespace Jack | |||
| jack_time_t fPeriodUsecs; | |||
| float fFilterCoefficient; /* set once, never altered */ | |||
| bool fUpdating; | |||
| public: | |||
| JackDelayLockedLoop() | |||
| {} | |||
| JackDelayLockedLoop(jack_nframes_t buffer_size, jack_nframes_t sample_rate) | |||
| { | |||
| Init(buffer_size, sample_rate); | |||
| } | |||
| void Init(jack_nframes_t buffer_size, jack_nframes_t sample_rate) | |||
| { | |||
| fFrames = 0; | |||
| @@ -95,7 +103,7 @@ namespace Jack | |||
| fSampleRate = sample_rate; | |||
| fPeriodUsecs = jack_time_t(1000000.f / fSampleRate * fBufferSize); // in microsec | |||
| } | |||
| void Init(jack_time_t callback_usecs) | |||
| { | |||
| fFrames = 0; | |||
| @@ -104,7 +112,7 @@ namespace Jack | |||
| fCurrentCallback = callback_usecs; | |||
| fNextWakeUp = callback_usecs + fPeriodUsecs; | |||
| } | |||
| void IncFrame(jack_time_t callback_usecs) | |||
| { | |||
| float delta = (int64_t)callback_usecs - (int64_t)fNextWakeUp; | |||
| @@ -114,41 +122,41 @@ namespace Jack | |||
| fSecondOrderIntegrator += 0.5f * fFilterCoefficient * delta; | |||
| fNextWakeUp = fCurrentWakeup + fPeriodUsecs + (int64_t) floorf((fFilterCoefficient * (delta + fSecondOrderIntegrator))); | |||
| } | |||
| jack_nframes_t Time2Frames(jack_time_t time) | |||
| { | |||
| long delta = (long) rint(((double) ((long long)(time - fCurrentWakeup)) / ((long long)(fNextWakeUp - fCurrentWakeup))) * fBufferSize); | |||
| return (delta < 0) ? ((fFrames > 0) ? fFrames : 1) : (fFrames + delta); | |||
| } | |||
| jack_time_t Frames2Time(jack_nframes_t frames) | |||
| { | |||
| long delta = (long) rint(((double) ((long long)(frames - fFrames)) * ((long long)(fNextWakeUp - fCurrentWakeup))) / fBufferSize); | |||
| return (delta < 0) ? ((fCurrentWakeup > 0) ? fCurrentWakeup : 1) : (fCurrentWakeup + delta); | |||
| } | |||
| jack_nframes_t CurFrame() | |||
| { | |||
| return fFrames; | |||
| } | |||
| jack_time_t CurTime() | |||
| { | |||
| return fCurrentWakeup; | |||
| } | |||
| } POST_PACKED_STRUCTURE; | |||
| class JackAtomicDelayLockedLoop : public JackAtomicState<JackDelayLockedLoop> | |||
| { | |||
| public: | |||
| JackAtomicDelayLockedLoop(jack_nframes_t buffer_size, jack_nframes_t sample_rate) | |||
| { | |||
| fState[0].Init(buffer_size, sample_rate); | |||
| fState[1].Init(buffer_size, sample_rate); | |||
| } | |||
| void Init(jack_time_t callback_usecs) | |||
| { | |||
| JackDelayLockedLoop* dll = WriteNextStateStart(); | |||
| @@ -156,7 +164,7 @@ namespace Jack | |||
| WriteNextStateStop(); | |||
| TrySwitchState(); // always succeed since there is only one writer | |||
| } | |||
| void Init(jack_nframes_t buffer_size, jack_nframes_t sample_rate) | |||
| { | |||
| JackDelayLockedLoop* dll = WriteNextStateStart(); | |||
| @@ -164,7 +172,7 @@ namespace Jack | |||
| WriteNextStateStop(); | |||
| TrySwitchState(); // always succeed since there is only one writer | |||
| } | |||
| void IncFrame(jack_time_t callback_usecs) | |||
| { | |||
| JackDelayLockedLoop* dll = WriteNextStateStart(); | |||
| @@ -172,44 +180,46 @@ namespace Jack | |||
| WriteNextStateStop(); | |||
| TrySwitchState(); // always succeed since there is only one writer | |||
| } | |||
| jack_nframes_t Time2Frames(jack_time_t time) | |||
| { | |||
| UInt16 next_index = GetCurrentIndex(); | |||
| UInt16 cur_index; | |||
| jack_nframes_t res; | |||
| do { | |||
| cur_index = next_index; | |||
| res = ReadCurrentState()->Time2Frames(time); | |||
| next_index = GetCurrentIndex(); | |||
| } while (cur_index != next_index); // Until a coherent state has been read | |||
| return res; | |||
| } | |||
| jack_time_t Frames2Time(jack_nframes_t frames) | |||
| { | |||
| UInt16 next_index = GetCurrentIndex(); | |||
| UInt16 cur_index; | |||
| jack_time_t res; | |||
| do { | |||
| cur_index = next_index; | |||
| res = ReadCurrentState()->Frames2Time(frames); | |||
| next_index = GetCurrentIndex(); | |||
| } while (cur_index != next_index); // Until a coherent state has been read | |||
| return res; | |||
| } | |||
| } POST_PACKED_STRUCTURE; | |||
| #endif | |||
| /* | |||
| Torben Hohn PI controler from JACK1 | |||
| */ | |||
| struct JackPIControler { | |||
| double resample_mean; | |||
| double static_resample_factor; | |||
| @@ -224,12 +234,12 @@ namespace Jack | |||
| double pclamp; | |||
| double controlquant; | |||
| int smooth_size; | |||
| double hann(double x) | |||
| { | |||
| return 0.5 * (1.0 - cos(2 * M_PI * x)); | |||
| } | |||
| JackPIControler(double resample_factor, int fir_size) | |||
| { | |||
| resample_mean = resample_factor; | |||
| @@ -239,7 +249,7 @@ namespace Jack | |||
| offset_differential_index = 0; | |||
| offset_integral = 0.0; | |||
| smooth_size = fir_size; | |||
| for (int i = 0; i < fir_size; i++) { | |||
| offset_array[i] = 0.0; | |||
| window_array[i] = hann(double(i) / (double(fir_size) - 1.0)); | |||
| @@ -251,19 +261,19 @@ namespace Jack | |||
| pclamp = 15.0; | |||
| controlquant = 10000.0; | |||
| } | |||
| ~JackPIControler() | |||
| { | |||
| delete[] offset_array; | |||
| delete[] window_array; | |||
| } | |||
| void Init(double resample_factor) | |||
| { | |||
| resample_mean = resample_factor; | |||
| static_resample_factor = resample_factor; | |||
| } | |||
| /* | |||
| double GetRatio(int fill_level) | |||
| { | |||
| @@ -271,14 +281,14 @@ namespace Jack | |||
| // Save offset. | |||
| offset_array[(offset_differential_index++) % smooth_size] = offset; | |||
| // Build the mean of the windowed offset array basically fir lowpassing. | |||
| double smooth_offset = 0.0; | |||
| for (int i = 0; i < smooth_size; i++) { | |||
| smooth_offset += offset_array[(i + offset_differential_index - 1) % smooth_size] * window_array[i]; | |||
| } | |||
| smooth_offset /= double(smooth_size); | |||
| // This is the integral of the smoothed_offset | |||
| offset_integral += smooth_offset; | |||
| @@ -286,13 +296,13 @@ namespace Jack | |||
| // It only used in the P component and the I component is used for the fine tuning anyways. | |||
| if (fabs(smooth_offset) < pclamp) | |||
| smooth_offset = 0.0; | |||
| // Ok, now this is the PI controller. | |||
| // Ok, now this is the PI controller. | |||
| // u(t) = K * (e(t) + 1/T \int e(t') dt') | |||
| // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T | |||
| double current_resample_factor | |||
| // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T | |||
| double current_resample_factor | |||
| = static_resample_factor - smooth_offset / catch_factor - offset_integral / catch_factor / catch_factor2; | |||
| // Now quantize this value around resample_mean, so that the noise which is in the integral component doesnt hurt. | |||
| current_resample_factor = floor((current_resample_factor - resample_mean) * controlquant + 0.5) / controlquant + resample_mean; | |||
| @@ -309,25 +319,25 @@ namespace Jack | |||
| // This is the integral of the smoothed_offset | |||
| offset_integral += smooth_offset; | |||
| // Ok, now this is the PI controller. | |||
| // Ok, now this is the PI controller. | |||
| // u(t) = K * (e(t) + 1/T \int e(t') dt') | |||
| // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T | |||
| // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T | |||
| return static_resample_factor - smooth_offset/catch_factor - offset_integral/catch_factor/catch_factor2; | |||
| } | |||
| void OurOfBounds() | |||
| { | |||
| int i; | |||
| // Set the resample_rate... we need to adjust the offset integral, to do this. | |||
| // first look at the PI controller, this code is just a special case, which should never execute once | |||
| // everything is swung in. | |||
| // everything is swung in. | |||
| offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2; | |||
| // Also clear the array. we are beginning a new control cycle. | |||
| for (i = 0; i < smooth_size; i++) { | |||
| offset_array[i] = 0.0; | |||
| } | |||
| } | |||
| }; | |||
| } | |||
| @@ -23,12 +23,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| #include "JackPlatformPlug.h" | |||
| #include "JackConstants.h" | |||
| #ifdef __CLIENTDEBUG__ | |||
| #ifdef __CLIENTDEBUG__ | |||
| #include <iostream> | |||
| #include <fstream> | |||
| #include <string> | |||
| #include <time.h> | |||
| #endif | |||
| #endif | |||
| namespace Jack | |||
| { | |||
| @@ -45,7 +45,7 @@ struct JackGlobals { | |||
| #ifndef WIN32 | |||
| static jack_thread_creator_t fJackThreadCreator; | |||
| #endif | |||
| #ifdef __CLIENTDEBUG__ | |||
| static std::ofstream* fStream; | |||
| static void CheckContext(const char* name); | |||
| @@ -26,7 +26,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| namespace Jack | |||
| { | |||
| JackNetAdapter::JackNetAdapter ( jack_client_t* jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ) | |||
| : JackAudioAdapterInterface ( buffer_size, sample_rate ), JackNetSlaveInterface(), fThread ( this ) | |||
| : JackAudioAdapterInterface ( buffer_size, sample_rate), JackNetSlaveInterface(), fThread ( this ) | |||
| { | |||
| jack_log ( "JackNetAdapter::JackNetAdapter" ); | |||
| @@ -40,8 +40,8 @@ namespace Jack | |||
| fSocket.GetName ( fParams.fSlaveNetName ); | |||
| fParams.fMtu = DEFAULT_MTU; | |||
| fParams.fTransportSync = 0; | |||
| fParams.fSendAudioChannels = 2; | |||
| fParams.fReturnAudioChannels = 2; | |||
| int send_audio = -1; | |||
| int return_audio = -1; | |||
| fParams.fSendMidiChannels = 0; | |||
| fParams.fReturnMidiChannels = 0; | |||
| fParams.fSampleRate = sample_rate; | |||
| @@ -71,10 +71,10 @@ namespace Jack | |||
| fParams.fMtu = param->value.i; | |||
| break; | |||
| case 'C' : | |||
| fParams.fSendAudioChannels = param->value.i; | |||
| send_audio = param->value.i; | |||
| break; | |||
| case 'P' : | |||
| fParams.fReturnAudioChannels = param->value.i; | |||
| return_audio = param->value.i; | |||
| break; | |||
| case 'n' : | |||
| strncpy ( fParams.fName, param->value.str, JACK_CLIENT_NAME_SIZE ); | |||
| @@ -105,7 +105,13 @@ namespace Jack | |||
| //set the socket parameters | |||
| fSocket.SetPort ( port ); | |||
| fSocket.SetAddress ( fMulticastIP, port ); | |||
| // If not set, takes deafault | |||
| fParams.fSendAudioChannels = (send_audio == -1) ? 2 : send_audio; | |||
| // If not set, takes deafault | |||
| fParams.fReturnAudioChannels = (return_audio == -1) ? 2 : return_audio; | |||
| //set the audio adapter interface channel values | |||
| SetInputs ( fParams.fSendAudioChannels ); | |||
| SetOutputs ( fParams.fReturnAudioChannels ); | |||
| @@ -117,18 +123,18 @@ namespace Jack | |||
| JackNetAdapter::~JackNetAdapter() | |||
| { | |||
| jack_log ( "JackNetAdapter::~JackNetAdapter" ); | |||
| jack_log ("JackNetAdapter::~JackNetAdapter"); | |||
| int port_index; | |||
| if ( fSoftCaptureBuffer ) | |||
| if (fSoftCaptureBuffer) | |||
| { | |||
| for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) | |||
| for (port_index = 0; port_index < fCaptureChannels; port_index++) | |||
| delete[] fSoftCaptureBuffer[port_index]; | |||
| delete[] fSoftCaptureBuffer; | |||
| } | |||
| if ( fSoftPlaybackBuffer ) | |||
| if (fSoftPlaybackBuffer) | |||
| { | |||
| for ( port_index = 0; port_index < fPlaybackChannels; port_index++ ) | |||
| for ( port_index = 0; port_index < fPlaybackChannels; port_index++) | |||
| delete[] fSoftPlaybackBuffer[port_index]; | |||
| delete[] fSoftPlaybackBuffer; | |||
| } | |||
| @@ -195,6 +201,8 @@ namespace Jack | |||
| } | |||
| //thread------------------------------------------------------------------------------ | |||
| // TODO : if failure, thread exist... need to restart ? | |||
| bool JackNetAdapter::Init() | |||
| { | |||
| jack_log ( "JackNetAdapter::Init" ); | |||
| @@ -202,24 +210,34 @@ namespace Jack | |||
| int port_index; | |||
| //init network connection | |||
| if ( !JackNetSlaveInterface::Init() ) | |||
| if (!JackNetSlaveInterface::Init()) { | |||
| jack_error("JackNetSlaveInterface::Init() error..." ); | |||
| return false; | |||
| } | |||
| //then set global parameters | |||
| SetParams(); | |||
| if (!SetParams()) { | |||
| jack_error("SetParams error..." ); | |||
| return false; | |||
| } | |||
| //set buffers | |||
| fSoftCaptureBuffer = new sample_t*[fCaptureChannels]; | |||
| for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) | |||
| { | |||
| fSoftCaptureBuffer[port_index] = new sample_t[fParams.fPeriodSize]; | |||
| fNetAudioCaptureBuffer->SetBuffer ( port_index, fSoftCaptureBuffer[port_index] ); | |||
| if (fCaptureChannels > 0) { | |||
| fSoftCaptureBuffer = new sample_t*[fCaptureChannels]; | |||
| for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) | |||
| { | |||
| fSoftCaptureBuffer[port_index] = new sample_t[fParams.fPeriodSize]; | |||
| fNetAudioCaptureBuffer->SetBuffer ( port_index, fSoftCaptureBuffer[port_index] ); | |||
| } | |||
| } | |||
| fSoftPlaybackBuffer = new sample_t*[fPlaybackChannels]; | |||
| for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) | |||
| { | |||
| fSoftPlaybackBuffer[port_index] = new sample_t[fParams.fPeriodSize]; | |||
| fNetAudioPlaybackBuffer->SetBuffer ( port_index, fSoftPlaybackBuffer[port_index] ); | |||
| if (fPlaybackChannels > 0) { | |||
| fSoftPlaybackBuffer = new sample_t*[fPlaybackChannels]; | |||
| for ( port_index = 0; port_index < fPlaybackChannels; port_index++ ) | |||
| { | |||
| fSoftPlaybackBuffer[port_index] = new sample_t[fParams.fPeriodSize]; | |||
| fNetAudioPlaybackBuffer->SetBuffer ( port_index, fSoftPlaybackBuffer[port_index] ); | |||
| } | |||
| } | |||
| //set audio adapter parameters | |||
| @@ -149,7 +149,10 @@ namespace Jack | |||
| } | |||
| //set global parameters | |||
| SetParams(); | |||
| if (!SetParams()) { | |||
| jack_error("SetParams error..." ); | |||
| return false; | |||
| } | |||
| // If -1 at conection time, in/out channels count is sent by the master | |||
| fCaptureChannels = fParams.fSendAudioChannels; | |||
| @@ -34,10 +34,11 @@ namespace Jack | |||
| protected: | |||
| void Initialize(); | |||
| session_params_t fParams; | |||
| JackNetSocket fSocket; | |||
| char fMulticastIP[32]; | |||
| uint fNSubProcess; | |||
| //headers | |||
| packet_header_t fTxHeader; | |||
| @@ -59,19 +60,12 @@ namespace Jack | |||
| NetAudioBuffer* fNetAudioCaptureBuffer; | |||
| NetAudioBuffer* fNetAudioPlaybackBuffer; | |||
| //sizes | |||
| int fAudioRxLen; | |||
| int fAudioTxLen; | |||
| int fPayloadSize; | |||
| //utility methods | |||
| void SetFramesPerPacket(); | |||
| int SetNetBufferSize(); | |||
| int GetNMidiPckt(); | |||
| bool IsNextPacket(); | |||
| void FreeNetworkBuffers(); | |||
| //virtual methods : depends on the sub class master/slave | |||
| virtual void SetParams(); | |||
| virtual bool SetParams(); | |||
| virtual bool Init() = 0; | |||
| //transport | |||
| @@ -111,10 +105,11 @@ namespace Jack | |||
| bool fRunning; | |||
| int fCycleOffset; | |||
| int fLastfCycleOffset; | |||
| bool Init(); | |||
| int SetRxTimeout(); | |||
| void SetParams(); | |||
| bool SetParams(); | |||
| void Exit(); | |||
| @@ -134,8 +129,7 @@ namespace Jack | |||
| bool IsSynched(); | |||
| public: | |||
| JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCycleOffset(0) | |||
| JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCycleOffset(0), fLastfCycleOffset(0) | |||
| {} | |||
| JackNetMasterInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ) | |||
| : JackNetInterface ( params, socket, multicast_ip ) | |||
| @@ -156,13 +150,13 @@ namespace Jack | |||
| static uint fSlaveCounter; | |||
| bool Init(); | |||
| bool InitConnection(); | |||
| bool InitConnection(int time_out); | |||
| bool InitRendering(); | |||
| net_status_t SendAvailableToMaster(); | |||
| net_status_t SendAvailableToMaster(long count = LONG_MAX); // long here (and not int...) | |||
| net_status_t SendStartToMaster(); | |||
| void SetParams(); | |||
| bool SetParams(); | |||
| int SyncRecv(); | |||
| int SyncSend(); | |||
| @@ -221,8 +215,11 @@ namespace Jack | |||
| #define SLAVE_SETUP_RETRY 5 | |||
| #define MASTER_INIT_TIMEOUT 1000000 // in usec | |||
| #define SLAVE_INIT_TIMEOUT 2000000 // in usec | |||
| #define SLAVE_INIT_TIMEOUT 1000000 // in usec | |||
| #define MAX_LATENCY 6 | |||
| #define CYCLE_OFFSET_FAST 0 | |||
| #define CYCLE_OFFSET_NORMAL 1 | |||
| #define CYCLE_OFFSET_SLOW 30 | |||
| #define MAX_LATENCY CYCLE_OFFSET_SLOW * 4 | |||
| #endif | |||
| @@ -113,11 +113,16 @@ namespace Jack | |||
| bool JackNetMaster::Init(bool auto_connect) | |||
| { | |||
| //network init | |||
| if ( !JackNetMasterInterface::Init() ) | |||
| if (!JackNetMasterInterface::Init()){ | |||
| jack_error("JackNetMasterInterface::Init() error..." ); | |||
| return false; | |||
| } | |||
| //set global parameters | |||
| SetParams(); | |||
| if (!SetParams()) { | |||
| jack_error("SetParams error..." ); | |||
| return false; | |||
| } | |||
| //jack client and process | |||
| jack_status_t status; | |||
| @@ -205,7 +210,6 @@ namespace Jack | |||
| } | |||
| } | |||
| //midi | |||
| for ( i = 0; i < fParams.fSendMidiChannels; i++ ) | |||
| { | |||
| @@ -626,8 +630,6 @@ namespace Jack | |||
| if ( fSocket.SetTimeOut ( 2000000 ) == SOCKET_ERROR ) | |||
| jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); | |||
| jack_info ( "Waiting for a slave..." ); | |||
| //main loop, wait for data, deal with it and wait again | |||
| do | |||
| { | |||
| @@ -681,7 +683,6 @@ namespace Jack | |||
| params.fID = ++fGlobalID; | |||
| params.fSampleRate = jack_get_sample_rate ( fManagerClient ); | |||
| params.fPeriodSize = jack_get_buffer_size ( fManagerClient ); | |||
| params.fBitdepth = 0; | |||
| if (params.fSendAudioChannels == -1) { | |||
| params.fSendAudioChannels = CountIO(JackPortIsPhysical | JackPortIsOutput); | |||
| @@ -19,6 +19,69 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| #include "JackNetTool.h" | |||
| #ifdef __APPLE__ | |||
| #include <mach/mach_time.h> | |||
| class HardwareClock | |||
| { | |||
| public: | |||
| HardwareClock(); | |||
| void Reset(); | |||
| void Update(); | |||
| float GetDeltaTime() const; | |||
| double GetTime() const; | |||
| private: | |||
| double m_clockToSeconds; | |||
| uint64_t m_startAbsTime; | |||
| uint64_t m_lastAbsTime; | |||
| double m_time; | |||
| float m_deltaTime; | |||
| }; | |||
| HardwareClock::HardwareClock() | |||
| { | |||
| mach_timebase_info_data_t info; | |||
| mach_timebase_info(&info); | |||
| m_clockToSeconds = (double)info.numer/info.denom/1000000000.0; | |||
| Reset(); | |||
| } | |||
| void HardwareClock::Reset() | |||
| { | |||
| m_startAbsTime = mach_absolute_time(); | |||
| m_lastAbsTime = m_startAbsTime; | |||
| m_time = m_startAbsTime*m_clockToSeconds; | |||
| m_deltaTime = 1.0f/60.0f; | |||
| } | |||
| void HardwareClock::Update() | |||
| { | |||
| const uint64_t currentTime = mach_absolute_time(); | |||
| const uint64_t dt = currentTime - m_lastAbsTime; | |||
| m_time = currentTime*m_clockToSeconds; | |||
| m_deltaTime = (double)dt*m_clockToSeconds; | |||
| m_lastAbsTime = currentTime; | |||
| } | |||
| float HardwareClock::GetDeltaTime() const | |||
| { | |||
| return m_deltaTime; | |||
| } | |||
| double HardwareClock::GetTime() const | |||
| { | |||
| return m_time; | |||
| } | |||
| #endif | |||
| using namespace std; | |||
| namespace Jack | |||
| @@ -35,6 +98,9 @@ namespace Jack | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||
| fPortBuffer[port_index] = NULL; | |||
| fNetBuffer = net_buffer; | |||
| fCycleSize = params->fMtu * (max(params->fSendMidiChannels, params->fReturnMidiChannels) * | |||
| params->fPeriodSize * sizeof(sample_t) / (params->fMtu - sizeof(packet_header_t))); | |||
| } | |||
| NetMidiBuffer::~NetMidiBuffer() | |||
| @@ -43,9 +109,21 @@ namespace Jack | |||
| delete[] fPortBuffer; | |||
| } | |||
| size_t NetMidiBuffer::GetSize() | |||
| size_t NetMidiBuffer::GetCycleSize() | |||
| { | |||
| return fMaxBufsize; | |||
| return fCycleSize; | |||
| } | |||
| int NetMidiBuffer::GetNumPackets() | |||
| { | |||
| /* | |||
| return (data_size % PACKET_AVAILABLE_SIZE) | |||
| ? (data_size / PACKET_AVAILABLE_SIZE + 1) | |||
| : data_size / PACKET_AVAILABLE_SIZE; | |||
| */ | |||
| //TODO | |||
| return 0; | |||
| } | |||
| void NetMidiBuffer::SetBuffer ( int index, JackMidiBuffer* buffer ) | |||
| @@ -119,103 +197,443 @@ namespace Jack | |||
| int NetMidiBuffer::RenderToNetwork ( int subcycle, size_t total_size ) | |||
| { | |||
| int size = total_size - subcycle * fMaxPcktSize; | |||
| int copy_size = ( size <= fMaxPcktSize ) ? size : fMaxPcktSize; | |||
| memcpy ( fNetBuffer, fBuffer + subcycle * fMaxPcktSize, copy_size ); | |||
| int copy_size = (size <= fMaxPcktSize) ? size : fMaxPcktSize; | |||
| memcpy(fNetBuffer, fBuffer + subcycle * fMaxPcktSize, copy_size); | |||
| return copy_size; | |||
| } | |||
| // net audio buffer ********************************************************************************* | |||
| NetAudioBuffer::NetAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) | |||
| NetFloatAudioBuffer::NetFloatAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) | |||
| : fPortBuffer(params, nports), fNetBuffer(net_buffer) | |||
| {} | |||
| NetFloatAudioBuffer::~NetFloatAudioBuffer() | |||
| {} | |||
| size_t NetFloatAudioBuffer::GetCycleSize() | |||
| { | |||
| return fPortBuffer.GetCycleSize(); | |||
| } | |||
| void NetFloatAudioBuffer::SetBuffer ( int index, sample_t* buffer ) | |||
| { | |||
| fPortBuffer.SetBuffer(index, buffer); | |||
| } | |||
| sample_t* NetFloatAudioBuffer::GetBuffer ( int index ) | |||
| { | |||
| return fPortBuffer.GetBuffer(index); | |||
| } | |||
| int NetFloatAudioBuffer::RenderFromJackPorts () | |||
| { | |||
| return fPortBuffer.RenderFromJackPorts(); | |||
| } | |||
| int NetFloatAudioBuffer::RenderToJackPorts () | |||
| { | |||
| return fPortBuffer.RenderToJackPorts(); | |||
| } | |||
| //network<->buffer | |||
| int NetFloatAudioBuffer::RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ) | |||
| { | |||
| return fPortBuffer.RenderFromNetwork(fNetBuffer, cycle, subcycle, copy_size); | |||
| } | |||
| int NetFloatAudioBuffer::RenderToNetwork (int subcycle, size_t total_size ) | |||
| { | |||
| return fPortBuffer.RenderToNetwork(fNetBuffer, subcycle, total_size); | |||
| } | |||
| // Celt audio buffer ********************************************************************************* | |||
| #ifdef CELT | |||
| #define KPS 32 | |||
| #define KPS_DIV 8 | |||
| NetCeltAudioBuffer::NetCeltAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer, int kbps ) | |||
| : fNetBuffer(net_buffer) | |||
| { | |||
| int res1, res2; | |||
| fNPorts = nports; | |||
| fPeriodSize = params->fPeriodSize; | |||
| fSubPeriodSize = params->fFramesPerPacket; | |||
| fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t ); | |||
| fCeltMode = new CELTMode *[fNPorts]; | |||
| fCeltEncoder = new CELTEncoder *[fNPorts]; | |||
| fCeltDecoder = new CELTDecoder *[fNPorts]; | |||
| memset(fCeltMode, 0, fNPorts * sizeof(CELTMode*)); | |||
| memset(fCeltEncoder, 0, fNPorts * sizeof(CELTEncoder*)); | |||
| memset(fCeltDecoder, 0, fNPorts * sizeof(CELTDecoder*)); | |||
| int error = CELT_OK; | |||
| for (int i = 0; i < fNPorts; i++) { | |||
| fCeltMode[i] = celt_mode_create(params->fSampleRate, params->fPeriodSize, &error); | |||
| if (error != CELT_OK) | |||
| goto error; | |||
| fCeltEncoder[i] = celt_encoder_create(fCeltMode[i], 1, &error); | |||
| if (error != CELT_OK) | |||
| goto error; | |||
| celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1)); | |||
| fCeltDecoder[i] = celt_decoder_create(fCeltMode[i], 1, &error); | |||
| if (error != CELT_OK) | |||
| goto error; | |||
| celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1)); | |||
| } | |||
| fPortBuffer = new sample_t* [fNPorts]; | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| fPortBuffer[port_index] = NULL; | |||
| fNetBuffer = net_buffer; | |||
| /* | |||
| celt_int32 lookahead; | |||
| celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); | |||
| */ | |||
| fCompressedSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8); | |||
| //fCompressedSizeByte = (params->fPeriodSize * sizeof(sample_t)) / KPS_DIV; // TODO | |||
| fCompressedBuffer = new unsigned char* [fNPorts]; | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| fCompressedBuffer[port_index] = new unsigned char[fCompressedSizeByte]; | |||
| jack_log("NetCeltAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte); | |||
| res1 = (fNPorts * fCompressedSizeByte) % (params->fMtu - sizeof(packet_header_t)); | |||
| res2 = (fNPorts * fCompressedSizeByte) / (params->fMtu - sizeof(packet_header_t)); | |||
| jack_log("NetCeltAudioBuffer res1 = %d res2 = %d", res1, res2); | |||
| fNumPackets = (res1) ? (res2 + 1) : res2; | |||
| fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets; | |||
| fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets; | |||
| jack_log("NetCeltAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize); | |||
| fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate); | |||
| fCycleSize = params->fMtu * fNumPackets; | |||
| fLastSubCycle = -1; | |||
| return; | |||
| error: | |||
| FreeCelt(); | |||
| throw std::bad_alloc(); | |||
| } | |||
| NetAudioBuffer::~NetAudioBuffer() | |||
| NetCeltAudioBuffer::~NetCeltAudioBuffer() | |||
| { | |||
| delete[] fPortBuffer; | |||
| FreeCelt(); | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| delete [] fCompressedBuffer[port_index]; | |||
| delete [] fCompressedBuffer; | |||
| delete [] fPortBuffer; | |||
| } | |||
| size_t NetAudioBuffer::GetSize() | |||
| void NetCeltAudioBuffer::FreeCelt() | |||
| { | |||
| return fNPorts * fSubPeriodBytesSize; | |||
| for (int i = 0; i < fNPorts; i++) { | |||
| if (fCeltEncoder[i]) | |||
| celt_encoder_destroy(fCeltEncoder[i]); | |||
| if (fCeltDecoder[i]) | |||
| celt_decoder_destroy(fCeltDecoder[i]); | |||
| if (fCeltMode[i]) | |||
| celt_mode_destroy(fCeltMode[i]); | |||
| } | |||
| delete [] fCeltMode; | |||
| delete [] fCeltEncoder; | |||
| delete [] fCeltDecoder; | |||
| } | |||
| void NetAudioBuffer::SetBuffer ( int index, sample_t* buffer ) | |||
| size_t NetCeltAudioBuffer::GetCycleSize() | |||
| { | |||
| return fCycleSize; | |||
| } | |||
| float NetCeltAudioBuffer::GetCycleDuration() | |||
| { | |||
| return fCycleDuration; | |||
| } | |||
| int NetCeltAudioBuffer::GetNumPackets() | |||
| { | |||
| return fNumPackets; | |||
| } | |||
| void NetCeltAudioBuffer::SetBuffer(int index, sample_t* buffer) | |||
| { | |||
| assert(fPortBuffer); | |||
| fPortBuffer[index] = buffer; | |||
| } | |||
| sample_t* NetAudioBuffer::GetBuffer ( int index ) | |||
| sample_t* NetCeltAudioBuffer::GetBuffer(int index) | |||
| { | |||
| assert(fPortBuffer); | |||
| return fPortBuffer[index]; | |||
| } | |||
| #ifdef __BIG_ENDIAN__ | |||
| static inline jack_default_audio_sample_t SwapFloat(jack_default_audio_sample_t f) | |||
| int NetCeltAudioBuffer::RenderFromJackPorts() | |||
| { | |||
| union | |||
| { | |||
| jack_default_audio_sample_t f; | |||
| unsigned char b[4]; | |||
| } dat1, dat2; | |||
| float floatbuf[fPeriodSize]; | |||
| dat1.f = f; | |||
| dat2.b[0] = dat1.b[3]; | |||
| dat2.b[1] = dat1.b[2]; | |||
| dat2.b[2] = dat1.b[1]; | |||
| dat2.b[3] = dat1.b[0]; | |||
| return dat2.f; | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) { | |||
| memcpy(floatbuf, fPortBuffer[port_index], fPeriodSize * sizeof(float)); | |||
| int res = celt_encode_float(fCeltEncoder[port_index], floatbuf, NULL, fCompressedBuffer[port_index], fCompressedSizeByte); | |||
| if (res != fCompressedSizeByte) { | |||
| jack_error("celt_encode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res); | |||
| } | |||
| } | |||
| return fNPorts * fCompressedSizeByte; // in bytes | |||
| } | |||
| void NetAudioBuffer::RenderFromJackPorts ( int subcycle ) | |||
| int NetCeltAudioBuffer::RenderToJackPorts() | |||
| { | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) { | |||
| jack_default_audio_sample_t* src = (jack_default_audio_sample_t*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); | |||
| jack_default_audio_sample_t* dst = (jack_default_audio_sample_t*)(fNetBuffer + port_index * fSubPeriodBytesSize); | |||
| for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(jack_default_audio_sample_t); sample++) { | |||
| dst[sample] = SwapFloat(src[sample]); | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) { | |||
| int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index]); | |||
| if (res != CELT_OK) { | |||
| jack_error("celt_decode_float error res = %d", fCompressedSizeByte, res); | |||
| } | |||
| } | |||
| fLastSubCycle = -1; | |||
| //return fPeriodSize * sizeof(sample_t); // in bytes; TODO | |||
| return 0; | |||
| } | |||
| void NetAudioBuffer::RenderToJackPorts ( int subcycle ) | |||
| //network<->buffer | |||
| int NetCeltAudioBuffer::RenderFromNetwork(int cycle, int subcycle, size_t copy_size) | |||
| { | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) { | |||
| jack_default_audio_sample_t* src = (jack_default_audio_sample_t*)(fNetBuffer + port_index * fSubPeriodBytesSize); | |||
| jack_default_audio_sample_t* dst = (jack_default_audio_sample_t*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); | |||
| for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(jack_default_audio_sample_t); sample++) { | |||
| dst[sample] = SwapFloat(src[sample]); | |||
| } | |||
| if (subcycle == fNumPackets - 1) { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| memcpy(fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize); | |||
| } else { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| memcpy(fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize); | |||
| } | |||
| if (subcycle != fLastSubCycle + 1) | |||
| jack_error("Packet(s) missing from... %d %d", fLastSubCycle, subcycle); | |||
| fLastSubCycle = subcycle; | |||
| return copy_size; | |||
| } | |||
| int NetCeltAudioBuffer::RenderToNetwork(int subcycle, size_t total_size) | |||
| { | |||
| if (subcycle == fNumPackets - 1) { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fLastSubPeriodBytesSize); | |||
| return fNPorts * fLastSubPeriodBytesSize; | |||
| } else { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + subcycle * fSubPeriodBytesSize, fSubPeriodBytesSize); | |||
| return fNPorts * fSubPeriodBytesSize; | |||
| } | |||
| return fNPorts * fSubPeriodBytesSize; | |||
| } | |||
| #else | |||
| #endif | |||
| void NetAudioBuffer::RenderFromJackPorts ( int subcycle ) | |||
| NetIntAudioBuffer::NetIntAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) | |||
| : fNetBuffer(net_buffer) | |||
| { | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||
| memcpy ( fNetBuffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize ); | |||
| int res1, res2; | |||
| fNPorts = nports; | |||
| fPeriodSize = params->fPeriodSize; | |||
| fPortBuffer = new sample_t* [fNPorts]; | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| fPortBuffer[port_index] = NULL; | |||
| fIntBuffer = new short* [fNPorts]; | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| fIntBuffer[port_index] = new short[fPeriodSize]; | |||
| fCompressedSizeByte = (params->fPeriodSize * sizeof(short)); | |||
| jack_log("fCompressedSizeByte %d", fCompressedSizeByte); | |||
| res1 = (fNPorts * fCompressedSizeByte) % (params->fMtu - sizeof(packet_header_t)); | |||
| res2 = (fNPorts * fCompressedSizeByte) / (params->fMtu - sizeof(packet_header_t)); | |||
| jack_log("res1 = %d res2 = %d", res1, res2); | |||
| fNumPackets = (res1) ? (res2 + 1) : res2; | |||
| fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets; | |||
| fSubPeriodSize = fSubPeriodBytesSize / sizeof(short); | |||
| fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets; | |||
| fLastSubPeriodSize = fLastSubPeriodBytesSize / sizeof(short); | |||
| jack_log("fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize); | |||
| fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate); | |||
| fCycleSize = params->fMtu * fNumPackets; | |||
| fLastSubCycle = -1; | |||
| return; | |||
| } | |||
| NetIntAudioBuffer::~NetIntAudioBuffer() | |||
| { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| delete [] fIntBuffer[port_index]; | |||
| delete [] fIntBuffer; | |||
| delete [] fPortBuffer; | |||
| } | |||
| void NetAudioBuffer::RenderToJackPorts ( int subcycle ) | |||
| size_t NetIntAudioBuffer::GetCycleSize() | |||
| { | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||
| memcpy ( fPortBuffer[port_index] + subcycle * fSubPeriodSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize ); | |||
| return fCycleSize; | |||
| } | |||
| #endif | |||
| float NetIntAudioBuffer::GetCycleDuration() | |||
| { | |||
| return fCycleDuration; | |||
| } | |||
| int NetIntAudioBuffer::GetNumPackets() | |||
| { | |||
| return fNumPackets; | |||
| } | |||
| void NetIntAudioBuffer::SetBuffer(int index, sample_t* buffer) | |||
| { | |||
| fPortBuffer[index] = buffer; | |||
| } | |||
| sample_t* NetIntAudioBuffer::GetBuffer(int index) | |||
| { | |||
| return fPortBuffer[index]; | |||
| } | |||
| int NetIntAudioBuffer::RenderFromJackPorts() | |||
| { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) { | |||
| for (unsigned int frame = 0; frame < fPeriodSize; frame++) | |||
| fIntBuffer[port_index][frame] = short(fPortBuffer[port_index][frame] * 32768.f); | |||
| } | |||
| return fNPorts * fCompressedSizeByte; // in bytes | |||
| } | |||
| int NetIntAudioBuffer::RenderToJackPorts() | |||
| { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) { | |||
| float coef = 1.f / 32768.f; | |||
| for (unsigned int frame = 0; frame < fPeriodSize; frame++) | |||
| fPortBuffer[port_index][frame] = float(fIntBuffer[port_index][frame] * coef); | |||
| } | |||
| fLastSubCycle = -1; | |||
| //return fPeriodSize * sizeof(sample_t); // in bytes; TODO | |||
| return 0; | |||
| } | |||
| //network<->buffer | |||
| int NetIntAudioBuffer::RenderFromNetwork(int cycle, int subcycle, size_t copy_size) | |||
| { | |||
| if (subcycle == fNumPackets - 1) { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| memcpy(fIntBuffer[port_index] + subcycle * fSubPeriodSize, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize); | |||
| } else { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| memcpy(fIntBuffer[port_index] + subcycle * fSubPeriodSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize); | |||
| } | |||
| if (subcycle != fLastSubCycle + 1) | |||
| jack_error("Packet(s) missing from... %d %d", fLastSubCycle, subcycle); | |||
| fLastSubCycle = subcycle; | |||
| return copy_size; | |||
| } | |||
| int NetIntAudioBuffer::RenderToNetwork(int subcycle, size_t total_size) | |||
| { | |||
| if (subcycle == fNumPackets - 1) { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fIntBuffer[port_index] + subcycle * fSubPeriodSize, fLastSubPeriodBytesSize); | |||
| return fNPorts * fLastSubPeriodBytesSize; | |||
| } else { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fIntBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize); | |||
| return fNPorts * fSubPeriodBytesSize; | |||
| } | |||
| } | |||
| // Buffered | |||
| /* | |||
| NetBufferedAudioBuffer::NetBufferedAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) | |||
| { | |||
| fMaxCycle = 0; | |||
| fNetBuffer = net_buffer; | |||
| for (int i = 0; i < AUDIO_BUFFER_SIZE; i++) { | |||
| fPortBuffer[i].Init(params, nports); | |||
| } | |||
| fJackPortBuffer = new sample_t* [nports]; | |||
| for ( uint32_t port_index = 0; port_index < nports; port_index++ ) | |||
| fJackPortBuffer[port_index] = NULL; | |||
| } | |||
| NetBufferedAudioBuffer::~NetBufferedAudioBuffer() | |||
| { | |||
| delete [] fJackPortBuffer; | |||
| } | |||
| size_t NetBufferedAudioBuffer::GetCycleSize() | |||
| { | |||
| return fPortBuffer[0].GetCycleSize(); | |||
| } | |||
| void NetBufferedAudioBuffer::SetBuffer ( int index, sample_t* buffer ) | |||
| { | |||
| fJackPortBuffer[index] = buffer; | |||
| } | |||
| sample_t* NetBufferedAudioBuffer::GetBuffer ( int index ) | |||
| { | |||
| return fJackPortBuffer[index]; | |||
| } | |||
| void NetBufferedAudioBuffer::RenderFromJackPorts (int subcycle ) | |||
| { | |||
| fPortBuffer[0].RenderFromJackPorts(fNetBuffer, subcycle); // Always use first buffer... | |||
| } | |||
| void NetBufferedAudioBuffer::RenderToJackPorts (int cycle, int subcycle) | |||
| { | |||
| if (cycle < fMaxCycle) { | |||
| jack_info("Wrong order fCycle %d subcycle %d fMaxCycle %d", cycle, subcycle, fMaxCycle); | |||
| } | |||
| fPortBuffer[cycle % AUDIO_BUFFER_SIZE].RenderToJackPorts(fNetBuffer, subcycle); | |||
| } | |||
| void NetBufferedAudioBuffer::FinishRenderToJackPorts (int cycle) | |||
| { | |||
| fMaxCycle = std::max(fMaxCycle, cycle); | |||
| fPortBuffer[(cycle + 1) % AUDIO_BUFFER_SIZE].Copy(fJackPortBuffer); // Copy internal buffer in JACK ports | |||
| } | |||
| */ | |||
| // SessionParams ************************************************************************************ | |||
| @@ -232,8 +650,7 @@ namespace Jack | |||
| dst_params->fReturnMidiChannels = htonl ( src_params->fReturnMidiChannels ); | |||
| dst_params->fSampleRate = htonl ( src_params->fSampleRate ); | |||
| dst_params->fPeriodSize = htonl ( src_params->fPeriodSize ); | |||
| dst_params->fFramesPerPacket = htonl ( src_params->fFramesPerPacket ); | |||
| dst_params->fBitdepth = htonl ( src_params->fBitdepth ); | |||
| dst_params->fSampleEncoder = htonl ( src_params->fSampleEncoder ); | |||
| dst_params->fSlaveSyncMode = htonl ( src_params->fSlaveSyncMode ); | |||
| } | |||
| @@ -250,15 +667,26 @@ namespace Jack | |||
| dst_params->fReturnMidiChannels = ntohl ( src_params->fReturnMidiChannels ); | |||
| dst_params->fSampleRate = ntohl ( src_params->fSampleRate ); | |||
| dst_params->fPeriodSize = ntohl ( src_params->fPeriodSize ); | |||
| dst_params->fFramesPerPacket = ntohl ( src_params->fFramesPerPacket ); | |||
| dst_params->fBitdepth = ntohl ( src_params->fBitdepth ); | |||
| dst_params->fSampleEncoder = ntohl ( src_params->fSampleEncoder ); | |||
| dst_params->fSlaveSyncMode = ntohl ( src_params->fSlaveSyncMode ); | |||
| } | |||
| SERVER_EXPORT void SessionParamsDisplay ( session_params_t* params ) | |||
| { | |||
| char bitdepth[16]; | |||
| ( params->fBitdepth ) ? sprintf ( bitdepth, "%u", params->fBitdepth ) : sprintf ( bitdepth, "%s", "float" ); | |||
| char encoder[16]; | |||
| switch ( params->fSampleEncoder ) | |||
| { | |||
| case JackFloatEncoder: | |||
| strcpy ( encoder, "float" ); | |||
| break; | |||
| case JackIntEncoder: | |||
| strcpy ( encoder, "integer" ); | |||
| break; | |||
| case JackCeltEncoder: | |||
| strcpy ( encoder, "CELT" ); | |||
| break; | |||
| } | |||
| char mode[8]; | |||
| switch ( params->fNetworkMode ) | |||
| { | |||
| @@ -284,9 +712,17 @@ namespace Jack | |||
| jack_info ( "Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels ); | |||
| jack_info ( "Sample rate : %u frames per second", params->fSampleRate ); | |||
| jack_info ( "Period size : %u frames per period", params->fPeriodSize ); | |||
| jack_info ( "Frames per packet : %u", params->fFramesPerPacket ); | |||
| jack_info ( "Packet per period : %u", (params->fFramesPerPacket != 0) ? params->fPeriodSize / params->fFramesPerPacket : 0); | |||
| jack_info ( "Bitdepth : %s", bitdepth ); | |||
| switch (params->fSampleEncoder) { | |||
| case (JackFloatEncoder): | |||
| jack_info ( "SampleEncoder : %s", "Float" ); | |||
| break; | |||
| case (JackIntEncoder): | |||
| jack_info ( "SampleEncoder : %s", "16 bits integer"); | |||
| break; | |||
| case (JackCeltEncoder): | |||
| jack_info ( "SampleEncoder : %s", "CELT"); | |||
| break; | |||
| }; | |||
| jack_info ( "Slave mode : %s", ( params->fSlaveSyncMode ) ? "sync" : "async" ); | |||
| jack_info ( "Network mode : %s", mode ); | |||
| jack_info ( "****************************************************" ); | |||
| @@ -340,9 +776,7 @@ namespace Jack | |||
| { | |||
| memcpy(dst_header, src_header, sizeof(packet_header_t)); | |||
| dst_header->fID = htonl ( src_header->fID ); | |||
| dst_header->fMidiDataSize = htonl ( src_header->fMidiDataSize ); | |||
| dst_header->fBitdepth = htonl ( src_header->fBitdepth ); | |||
| dst_header->fNMidiPckt = htonl ( src_header->fNMidiPckt ); | |||
| dst_header->fNumPacket = htonl ( src_header->fNumPacket ); | |||
| dst_header->fPacketSize = htonl ( src_header->fPacketSize ); | |||
| dst_header->fCycle = htonl ( src_header->fCycle ); | |||
| dst_header->fSubCycle = htonl ( src_header->fSubCycle ); | |||
| @@ -353,9 +787,7 @@ namespace Jack | |||
| { | |||
| memcpy(dst_header, src_header, sizeof(packet_header_t)); | |||
| dst_header->fID = ntohl ( src_header->fID ); | |||
| dst_header->fMidiDataSize = ntohl ( src_header->fMidiDataSize ); | |||
| dst_header->fBitdepth = ntohl ( src_header->fBitdepth ); | |||
| dst_header->fNMidiPckt = ntohl ( src_header->fNMidiPckt ); | |||
| dst_header->fNumPacket = ntohl ( src_header->fNumPacket ); | |||
| dst_header->fPacketSize = ntohl ( src_header->fPacketSize ); | |||
| dst_header->fCycle = ntohl ( src_header->fCycle ); | |||
| dst_header->fSubCycle = ntohl ( src_header->fSubCycle ); | |||
| @@ -365,15 +797,13 @@ namespace Jack | |||
| SERVER_EXPORT void PacketHeaderDisplay ( packet_header_t* header ) | |||
| { | |||
| char bitdepth[16]; | |||
| ( header->fBitdepth ) ? sprintf ( bitdepth, "%u", header->fBitdepth ) : sprintf ( bitdepth, "%s", "float" ); | |||
| jack_info ( "********************Header********************" ); | |||
| jack_info ( "Data type : %c", header->fDataType ); | |||
| jack_info ( "Data stream : %c", header->fDataStream ); | |||
| jack_info ( "ID : %u", header->fID ); | |||
| jack_info ( "Cycle : %u", header->fCycle ); | |||
| jack_info ( "SubCycle : %u", header->fSubCycle ); | |||
| jack_info ( "Midi packets : %u", header->fNMidiPckt ); | |||
| jack_info ( "Midi data size : %u", header->fMidiDataSize ); | |||
| jack_info ( "Midi packets : %u", header->fNumPacket ); | |||
| jack_info ( "Last packet : '%s'", ( header->fIsLastPckt ) ? "yes" : "no" ); | |||
| jack_info ( "Bitdepth : %s", bitdepth ); | |||
| jack_info ( "**********************************************" ); | |||
| @@ -47,6 +47,13 @@ namespace Jack | |||
| typedef struct sockaddr socket_address_t; | |||
| typedef struct in_addr address_t; | |||
| typedef jack_default_audio_sample_t sample_t; | |||
| enum JackNetEncoder { | |||
| JackFloatEncoder = 0, | |||
| JackIntEncoder = 1, | |||
| JackCeltEncoder = 2, | |||
| }; | |||
| //session params ****************************************************************************** | |||
| @@ -67,8 +74,8 @@ namespace Jack | |||
| are kept in LITTLE_ENDIAN format (to avoid 2 conversions in the more common LITTLE_ENDIAN <==> LITTLE_ENDIAN connection case). | |||
| */ | |||
| #define MASTER_PROTOCOL 1 | |||
| #define SLAVE_PROTOCOL 1 | |||
| #define MASTER_PROTOCOL 2 | |||
| #define SLAVE_PROTOCOL 2 | |||
| struct _session_params | |||
| { | |||
| @@ -87,8 +94,8 @@ namespace Jack | |||
| int32_t fReturnMidiChannels; //number of slave->master midi channels | |||
| uint32_t fSampleRate; //session sample rate | |||
| uint32_t fPeriodSize; //period size | |||
| uint32_t fFramesPerPacket; //complete frames per packet | |||
| uint32_t fBitdepth; //samples bitdepth (unused) | |||
| uint32_t fSampleEncoder; //samples encoder | |||
| uint32_t fKBps; // KB per second for CELT encoder | |||
| uint32_t fSlaveSyncMode; //is the slave in sync mode ? | |||
| char fNetworkMode; //fast, normal or slow mode | |||
| }; | |||
| @@ -158,15 +165,11 @@ namespace Jack | |||
| char fDataType; //a for audio, m for midi and s for sync | |||
| char fDataStream; //s for send, r for return | |||
| uint32_t fID; //unique ID of the slave | |||
| uint32_t fBitdepth; //bitdepth of the data samples | |||
| uint32_t fMidiDataSize; //size of midi data in bytes | |||
| uint32_t fNMidiPckt; //number of midi packets of the cycle | |||
| uint32_t fNumPacket; //number of data packets of the cycle | |||
| uint32_t fPacketSize; //packet size in bytes | |||
| uint32_t fCycle; //process cycle counter | |||
| uint32_t fSubCycle; //midi/audio subcycle counter | |||
| uint32_t fIsLastPckt; //is it the last packet of a given cycle ('y' or 'n') | |||
| char fASyncWrongCycle; //is the current async cycle wrong (slave's side; 'y' or 'n') | |||
| char fFree[26]; //unused | |||
| }; | |||
| //net timebase master | |||
| @@ -199,8 +202,8 @@ namespace Jack | |||
| int32_t fState; //current cycle state | |||
| jack_position_t fPosition; //current cycle position | |||
| }; | |||
| //midi data *********************************************************************************** | |||
| //midi data *********************************************************************************** | |||
| /** | |||
| \Brief Midi buffer and operations class | |||
| @@ -220,24 +223,35 @@ namespace Jack | |||
| class SERVER_EXPORT NetMidiBuffer | |||
| { | |||
| private: | |||
| int fNPorts; | |||
| size_t fMaxBufsize; | |||
| int fMaxPcktSize; | |||
| char* fBuffer; | |||
| char* fNetBuffer; | |||
| JackMidiBuffer** fPortBuffer; | |||
| size_t fCycleSize; // needed size in bytes ofr an entire cycle | |||
| public: | |||
| NetMidiBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); | |||
| ~NetMidiBuffer(); | |||
| void Reset(); | |||
| size_t GetSize(); | |||
| // needed size in bytes for an entire cycle | |||
| size_t GetCycleSize(); | |||
| int GetNumPackets(); | |||
| //utility | |||
| void DisplayEvents(); | |||
| //jack<->buffer | |||
| int RenderFromJackPorts(); | |||
| int RenderToJackPorts(); | |||
| //network<->buffer | |||
| int RenderFromNetwork ( int subcycle, size_t copy_size ); | |||
| int RenderToNetwork ( int subcycle, size_t total_size ); | |||
| @@ -248,6 +262,36 @@ namespace Jack | |||
| // audio data ********************************************************************************* | |||
| class SERVER_EXPORT NetAudioBuffer | |||
| { | |||
| public: | |||
| NetAudioBuffer () | |||
| {} | |||
| virtual ~NetAudioBuffer() | |||
| {} | |||
| // needed syze in bytes ofr an entire cycle | |||
| virtual size_t GetCycleSize() = 0; | |||
| // cycle duration in sec | |||
| virtual float GetCycleDuration() = 0; | |||
| virtual int GetNumPackets() = 0; | |||
| //jack<->buffer | |||
| virtual int RenderFromJackPorts () = 0; | |||
| virtual int RenderToJackPorts () = 0; | |||
| //network<->buffer | |||
| virtual int RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ) = 0; | |||
| virtual int RenderToNetwork (int subcycle, size_t total_size ) = 0; | |||
| virtual void SetBuffer ( int index, sample_t* buffer ) = 0; | |||
| virtual sample_t* GetBuffer ( int index ) = 0; | |||
| }; | |||
| /** | |||
| \Brief Audio buffer and operations class | |||
| @@ -257,28 +301,417 @@ namespace Jack | |||
| So there is no need of an intermediate buffer as in NetMidiBuffer. | |||
| */ | |||
| struct JackPortList { | |||
| jack_nframes_t fPeriodSize; | |||
| jack_nframes_t fSubPeriodSize; | |||
| size_t fSubPeriodBytesSize; | |||
| sample_t** fPortBuffer; | |||
| int fNPorts; | |||
| size_t fCycleSize; // needed size in bytes for an entire cycle | |||
| float fCycleDuration; // in sec | |||
| int fLastSubCycle; | |||
| JackPortList(session_params_t* params, uint32_t nports) | |||
| { | |||
| fNPorts = nports; | |||
| fPeriodSize = params->fPeriodSize; | |||
| if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) { | |||
| fSubPeriodSize = params->fPeriodSize; | |||
| } else { | |||
| jack_nframes_t period = (int) powf(2.f, (int) (log (float ((params->fMtu - sizeof(packet_header_t))) | |||
| / (max(params->fReturnAudioChannels, params->fSendAudioChannels) * sizeof(sample_t))) / log(2.))); | |||
| fSubPeriodSize = (period > params->fPeriodSize) ? params->fPeriodSize : period; | |||
| } | |||
| fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t); | |||
| fPortBuffer = new sample_t* [fNPorts]; | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| fPortBuffer[port_index] = NULL; | |||
| fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate); | |||
| fCycleSize = params->fMtu * (fPeriodSize / fSubPeriodSize); | |||
| fLastSubCycle = -1; | |||
| } | |||
| int GetNumPackets() | |||
| { | |||
| return fPeriodSize / fSubPeriodSize; | |||
| } | |||
| JackPortList() | |||
| { | |||
| fNPorts = 0; | |||
| fPeriodSize = 0; | |||
| fSubPeriodSize = 0; | |||
| fSubPeriodBytesSize = 0; | |||
| fPortBuffer = 0; | |||
| } | |||
| ~JackPortList() | |||
| { | |||
| delete [] fPortBuffer; | |||
| } | |||
| void SetBuffer( int index, sample_t* buffer ) | |||
| { | |||
| fPortBuffer[index] = buffer; | |||
| } | |||
| sample_t* GetBuffer ( int index ) | |||
| { | |||
| return fPortBuffer[index]; | |||
| } | |||
| void Copy(sample_t** buffers) | |||
| { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| memcpy(buffers[port_index], fPortBuffer[port_index], fPeriodSize * sizeof(float)); | |||
| } | |||
| // needed syze in bytes ofr an entire cycle | |||
| size_t GetCycleSize() | |||
| { | |||
| return fCycleSize; | |||
| } | |||
| // cycle duration in sec | |||
| float GetCycleDuration() | |||
| { | |||
| return fCycleDuration; | |||
| } | |||
| #ifdef __BIG_ENDIAN__ | |||
| static inline float SwapFloat(float f) | |||
| { | |||
| union | |||
| { | |||
| float f; | |||
| unsigned char b[4]; | |||
| } dat1, dat2; | |||
| dat1.f = f; | |||
| dat2.b[0] = dat1.b[3]; | |||
| dat2.b[1] = dat1.b[2]; | |||
| dat2.b[2] = dat1.b[1]; | |||
| dat2.b[3] = dat1.b[0]; | |||
| return dat2.f; | |||
| } | |||
| int RenderFromJackPorts () | |||
| { | |||
| return fNPorts * fSubPeriodBytesSize; // in bytes | |||
| } | |||
| int RenderToJackPorts () | |||
| { | |||
| return fPeriodSize * sizeof(sample_t); // in bytes TODO | |||
| } | |||
| //network<->buffer | |||
| int RenderFromNetwork(char* net_buffer, int cycle, int subcycle, size_t copy_size) | |||
| { | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) { | |||
| float* src = (float*)(net_buffer + port_index * fSubPeriodBytesSize); | |||
| float* dst = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); | |||
| for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) { | |||
| dst[sample] = SwapFloat(src[sample]); | |||
| } | |||
| } | |||
| return copy_size; | |||
| } | |||
| int RenderToNetwork(char* net_buffer, int subcycle, size_t total_size) | |||
| { | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) { | |||
| float* src = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); | |||
| float* dst = (float*)(net_buffer + port_index * fSubPeriodBytesSize); | |||
| for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) { | |||
| dst[sample] = SwapFloat(src[sample]); | |||
| } | |||
| } | |||
| return fNPorts * fSubPeriodBytesSize; | |||
| } | |||
| #else | |||
| int RenderFromJackPorts () | |||
| { | |||
| return fNPorts * fSubPeriodBytesSize; // in bytes | |||
| } | |||
| int RenderToJackPorts () | |||
| { | |||
| fLastSubCycle = -1; | |||
| return fPeriodSize * sizeof(sample_t); // in bytes; TODO | |||
| } | |||
| //network<->buffer | |||
| int RenderFromNetwork(char* net_buffer, int cycle, int subcycle, size_t copy_size) | |||
| { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| memcpy(fPortBuffer[port_index] + subcycle * fSubPeriodSize, net_buffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize); | |||
| if (subcycle != fLastSubCycle + 1) { | |||
| jack_error("Packet(s) missing from... %d %d", fLastSubCycle, subcycle); | |||
| } | |||
| fLastSubCycle = subcycle; | |||
| return copy_size; | |||
| } | |||
| int RenderToNetwork(char* net_buffer,int subcycle, size_t total_size) | |||
| { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| memcpy(net_buffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize); | |||
| return fNPorts * fSubPeriodBytesSize; | |||
| } | |||
| #endif | |||
| }; | |||
| struct JackPortListAllocate : public JackPortList { | |||
| JackPortListAllocate() | |||
| { | |||
| fNPorts = 0; | |||
| fPeriodSize = 0; | |||
| fSubPeriodSize = 0; | |||
| fSubPeriodBytesSize = 0; | |||
| fPortBuffer = 0; | |||
| } | |||
| ~JackPortListAllocate() | |||
| { | |||
| for (int port_index = 0; port_index < fNPorts; port_index++) | |||
| delete [] fPortBuffer[port_index]; | |||
| delete [] fPortBuffer; | |||
| } | |||
| void Init(session_params_t* params, uint32_t nports) | |||
| { | |||
| fNPorts = nports; | |||
| fPeriodSize = params->fPeriodSize; | |||
| if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) { | |||
| fSubPeriodSize = params->fPeriodSize; | |||
| } else { | |||
| jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float ((params->fMtu - sizeof(packet_header_t))) | |||
| / ( max ( params->fReturnAudioChannels, params->fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) ); | |||
| fSubPeriodSize = ( period > params->fPeriodSize ) ? params->fPeriodSize : period; | |||
| } | |||
| fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t ); | |||
| fPortBuffer = new sample_t* [fNPorts]; | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||
| fPortBuffer[port_index] = new sample_t[fPeriodSize]; | |||
| } | |||
| }; | |||
| class SERVER_EXPORT NetAudioBuffer | |||
| class SERVER_EXPORT NetFloatAudioBuffer : public NetAudioBuffer | |||
| { | |||
| private: | |||
| int fNPorts; | |||
| JackPortList fPortBuffer; | |||
| char* fNetBuffer; | |||
| public: | |||
| NetFloatAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); | |||
| ~NetFloatAudioBuffer(); | |||
| // needed size in bytes for an entire cycle | |||
| size_t GetCycleSize(); | |||
| // cycle duration in sec | |||
| float GetCycleDuration() | |||
| { | |||
| return fPortBuffer.GetCycleDuration(); | |||
| } | |||
| int GetNumPackets() | |||
| { | |||
| return fPortBuffer.GetNumPackets(); | |||
| } | |||
| //jack<->buffer | |||
| int RenderFromJackPorts (); | |||
| int RenderToJackPorts (); | |||
| void SetBuffer ( int index, sample_t* buffer ); | |||
| sample_t* GetBuffer ( int index ); | |||
| //network<->buffer | |||
| int RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ); | |||
| int RenderToNetwork (int subcycle, size_t total_size ); | |||
| }; | |||
| #define CELT 1 | |||
| #ifdef CELT | |||
| #include <celt/celt.h> | |||
| class SERVER_EXPORT NetCeltAudioBuffer : public NetAudioBuffer | |||
| { | |||
| private: | |||
| CELTMode ** fCeltMode; | |||
| CELTEncoder ** fCeltEncoder; | |||
| CELTDecoder ** fCeltDecoder; | |||
| int fCompressedSizeByte; | |||
| jack_nframes_t fPeriodSize; | |||
| jack_nframes_t fSubPeriodSize; | |||
| int fNumPackets; | |||
| float fCycleDuration; // in sec | |||
| size_t fCycleSize; // needed size in bytes for an entire cycle | |||
| size_t fSubPeriodBytesSize; | |||
| size_t fLastSubPeriodBytesSize; | |||
| sample_t** fPortBuffer; | |||
| char* fNetBuffer; | |||
| unsigned char ** fCompressedBuffer; | |||
| int fNPorts; | |||
| int fLastSubCycle; | |||
| void FreeCelt(); | |||
| public: | |||
| NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps); | |||
| ~NetCeltAudioBuffer(); | |||
| // needed size in bytes for an entire cycle | |||
| size_t GetCycleSize(); | |||
| // cycle duration in sec | |||
| float GetCycleDuration(); | |||
| int GetNumPackets(); | |||
| void SetBuffer(int index, sample_t* buffer); | |||
| sample_t* GetBuffer(int index); | |||
| //jack<->buffer | |||
| int RenderFromJackPorts(); | |||
| int RenderToJackPorts(); | |||
| //network<->buffer | |||
| int RenderFromNetwork(int cycle, int subcycle, size_t copy_size); | |||
| int RenderToNetwork(int subcycle, size_t total_size); | |||
| }; | |||
| #endif | |||
| class SERVER_EXPORT NetIntAudioBuffer : public NetAudioBuffer | |||
| { | |||
| private: | |||
| int fCompressedSizeByte; | |||
| jack_nframes_t fPeriodSize; | |||
| int fNumPackets; | |||
| float fCycleDuration; // in sec | |||
| size_t fCycleSize; // needed size in bytes for an entire cycle | |||
| size_t fSubPeriodSize; | |||
| size_t fSubPeriodBytesSize; | |||
| size_t fLastSubPeriodSize;; | |||
| size_t fLastSubPeriodBytesSize; | |||
| sample_t** fPortBuffer; | |||
| char* fNetBuffer; | |||
| short ** fIntBuffer; | |||
| int fNPorts; | |||
| int fLastSubCycle; | |||
| public: | |||
| NetAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); | |||
| ~NetAudioBuffer(); | |||
| NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer); | |||
| ~NetIntAudioBuffer(); | |||
| // needed size in bytes for an entire cycle | |||
| size_t GetCycleSize(); | |||
| // cycle duration in sec | |||
| float GetCycleDuration(); | |||
| int GetNumPackets(); | |||
| void SetBuffer(int index, sample_t* buffer); | |||
| sample_t* GetBuffer(int index); | |||
| //jack<->buffer | |||
| int RenderFromJackPorts(); | |||
| int RenderToJackPorts(); | |||
| //network<->buffer | |||
| int RenderFromNetwork(int cycle, int subcycle, size_t copy_size); | |||
| int RenderToNetwork(int subcycle, size_t total_size); | |||
| }; | |||
| size_t GetSize(); | |||
| #define AUDIO_BUFFER_SIZE 8 | |||
| /* | |||
| class SERVER_EXPORT NetBufferedAudioBuffer : public NetAudioBuffer | |||
| { | |||
| private: | |||
| char* fNetBuffer; | |||
| JackPortListAllocate fPortBuffer[AUDIO_BUFFER_SIZE]; | |||
| sample_t** fJackPortBuffer; | |||
| int fMaxCycle; | |||
| public: | |||
| NetBufferedAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); | |||
| ~NetBufferedAudioBuffer(); | |||
| // needed syze in bytes ofr an entire cycle | |||
| size_t GetCycleSize(); | |||
| // cycle duration in sec | |||
| float GetCycleDuration() | |||
| { | |||
| return fPortBuffer[0].GetCycleDuration(); | |||
| } | |||
| //jack<->buffer | |||
| void RenderFromJackPorts ( int subcycle ); | |||
| void RenderToJackPorts ( int subcycle ); | |||
| int RenderFromJackPorts (int subcycle ); | |||
| int RenderToJackPorts ( int cycle, int subcycle); | |||
| //void FinishRenderToJackPorts (int cycle); | |||
| //network<->buffer | |||
| int RenderFromNetwork ( int subcycle, size_t copy_size ) | |||
| { | |||
| // TODO | |||
| return 0; | |||
| } | |||
| int RenderToNetwork ( int subcycle, size_t total_size ) | |||
| { | |||
| // TODO | |||
| return 0; | |||
| } | |||
| void SetBuffer ( int index, sample_t* buffer ); | |||
| sample_t* GetBuffer ( int index ); | |||
| }; | |||
| */ | |||
| //utility ************************************************************************************* | |||
| @@ -39,6 +39,7 @@ JackResampler::~JackResampler() | |||
| void JackResampler::Reset(unsigned int new_size) | |||
| { | |||
| fRingBufferSize = new_size; | |||
| jack_ringbuffer_reset(fRingBuffer); | |||
| jack_ringbuffer_reset_size(fRingBuffer, sizeof(jack_default_audio_sample_t) * fRingBufferSize); | |||
| jack_ringbuffer_read_advance(fRingBuffer, (sizeof(jack_default_audio_sample_t) * fRingBufferSize / 2)); | |||
| } | |||
| @@ -81,6 +82,34 @@ unsigned int JackResampler::Write(jack_default_audio_sample_t* buffer, unsigned | |||
| } | |||
| } | |||
| unsigned int JackResampler::Read(void* buffer, unsigned int bytes) | |||
| { | |||
| size_t len = jack_ringbuffer_read_space(fRingBuffer); | |||
| jack_log("JackResampler::Read input available = %ld", len); | |||
| if (len < bytes) { | |||
| jack_error("JackResampler::Read : producer too slow, missing bytes = %d", bytes); | |||
| return 0; | |||
| } else { | |||
| jack_ringbuffer_read(fRingBuffer, (char*)buffer, bytes); | |||
| return bytes; | |||
| } | |||
| } | |||
| unsigned int JackResampler::Write(void* buffer, unsigned int bytes) | |||
| { | |||
| size_t len = jack_ringbuffer_write_space(fRingBuffer); | |||
| jack_log("JackResampler::Write output available = %ld", len); | |||
| if (len < bytes) { | |||
| jack_error("JackResampler::Write : consumer too slow, skip bytes = %d", bytes); | |||
| return 0; | |||
| } else { | |||
| jack_ringbuffer_write(fRingBuffer, (char*)buffer, bytes); | |||
| return bytes; | |||
| } | |||
| } | |||
| unsigned int JackResampler::ReadResample(jack_default_audio_sample_t* buffer, unsigned int frames) | |||
| { | |||
| return Read(buffer, frames); | |||
| @@ -61,6 +61,9 @@ class JackResampler | |||
| virtual unsigned int Read(jack_default_audio_sample_t* buffer, unsigned int frames); | |||
| virtual unsigned int Write(jack_default_audio_sample_t* buffer, unsigned int frames); | |||
| virtual unsigned int Read(void* buffer, unsigned int bytes); | |||
| virtual unsigned int Write(void* buffer, unsigned int bytes); | |||
| virtual unsigned int ReadSpace(); | |||
| virtual unsigned int WriteSpace(); | |||
| @@ -141,7 +141,7 @@ namespace Jack | |||
| T Add ( T measure_point ) | |||
| { | |||
| return fCurrentMeasure[fMeasureId++] = measure_point; | |||
| return fCurrentMeasure[fMeasureId++] = measure_point; | |||
| } | |||
| uint32_t AddLast ( T measure_point ) | |||
| @@ -70,6 +70,7 @@ class SERVER_EXPORT JackWaitThreadedDriver : public JackThreadedDriver | |||
| } else { | |||
| jack_error("Initing net driver fails..."); | |||
| } | |||
| return false; | |||
| } | |||
| @@ -0,0 +1,321 @@ | |||
| /* | |||
| Copyright (C) 2009-2010 Grame | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU Lesser General Public License as published by | |||
| the Free Software Foundation; either version 2.1 of the License, or | |||
| (at your option) any later version. | |||
| This program is distributed in the hope that it will be useful, | |||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU Lesser General Public License for more details. | |||
| You should have received a copy of the GNU Lesser General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| #ifndef __net_h__ | |||
| #define __net_h__ | |||
| #ifdef __cplusplus | |||
| extern "C" | |||
| { | |||
| #endif | |||
| #include <jack/systemdeps.h> | |||
| #include <jack/types.h> | |||
| #define DEFAULT_MULTICAST_IP "225.3.19.154" | |||
| #define DEFAULT_PORT 19000 | |||
| #define DEFAULT_MTU 1500 | |||
| #define MASTER_NAME_SIZE 256 | |||
| #define SOCKET_ERROR -1 | |||
| enum JackNetMode { | |||
| JackFastMode = 'f', | |||
| JackNormalMode = 'n', | |||
| JackSlowMode = 's', | |||
| }; | |||
| enum JackNetEncoder { | |||
| JackFloatEncoder = 0, // Samples are transmitted as float | |||
| JackIntEncoder = 1, // Samples are transmitted as 16 bits integer | |||
| JackCeltEncoder = 2, // Samples are transmitted using CELT codec (http://www.celt-codec.org/) | |||
| }; | |||
| typedef struct { | |||
| int audio_input; // from master or to slave | |||
| int audio_output; // to master or from slave | |||
| int midi_input; // from master or to slave | |||
| int midi_output; // to master or from slave | |||
| int mtu; // network Maximum Transmission Unit | |||
| int time_out; // in second, -1 means in infinite | |||
| int encoder; // Encoder type (one of JackNetEncoder) | |||
| int kbps; // KB per second for CELT encoder | |||
| char mode; | |||
| } jack_slave_t; | |||
| typedef struct { | |||
| jack_nframes_t buffer_size; | |||
| jack_nframes_t sample_rate; | |||
| char master_name[MASTER_NAME_SIZE]; | |||
| } jack_master_t; | |||
| /** | |||
| * jack_net_t is an opaque type. You may only access it using the | |||
| * API provided. | |||
| */ | |||
| typedef struct _jack_net_slave jack_net_slave_t; | |||
| /** | |||
| * Open a network connection with the master machine. | |||
| * @param ip the multicast address of the master | |||
| * @param port the connection port | |||
| * @param request a connection request structure | |||
| * @param result a connection result structure | |||
| * | |||
| * @return Opaque net handle if successful or NULL in case of error. | |||
| */ | |||
| jack_net_slave_t* jack_net_slave_open(const char* ip, int port, const char* name, jack_slave_t* request, jack_master_t* result); | |||
| /** | |||
| * Close the network connection with the master machine. | |||
| * @param net the network connection to be closed | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int jack_net_slave_close(jack_net_slave_t* net); | |||
| /** | |||
| * Prototype for Process callback. | |||
| * @param nframes buffer size | |||
| * @param audio_input number of audio inputs | |||
| * @param audio_input_buffer an array of audio input buffers (from master) | |||
| * @param midi_input number of MIDI inputs | |||
| * @param midi_input_buffer an array of MIDI input buffers (from master) | |||
| * @param audio_output number of audio outputs | |||
| * @param audio_output_buffer an array of audio output buffers (to master) | |||
| * @param midi_output number of MIDI outputs | |||
| * @param midi_output_buffer an array of MIDI output buffers (to master) | |||
| * @param arg pointer to a client supplied structure supplied by jack_set_net_process_callback(). | |||
| * | |||
| * @return zero on success, non-zero on error | |||
| */ | |||
| typedef int (* JackNetSlaveProcessCallback) (jack_nframes_t buffer_size, | |||
| int audio_input, | |||
| float** audio_input_buffer, | |||
| int midi_input, | |||
| void** midi_input_buffer, | |||
| int audio_output, | |||
| float** audio_output_buffer, | |||
| int midi_output, | |||
| void** midi_output_buffer, | |||
| void* data); | |||
| /** | |||
| * Set network process callback. | |||
| * @param net the network connection | |||
| * @param net_callback the process callback | |||
| * @param arg pointer to a client supplied structure | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int jack_set_net_slave_process_callback(jack_net_slave_t * net, JackNetSlaveProcessCallback net_callback, void *arg); | |||
| /** | |||
| * Start processing thread, the net_callback will start to be called. | |||
| * @param net the network connection | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int jack_net_slave_activate(jack_net_slave_t* net); | |||
| /** | |||
| * Stop processing thread. | |||
| * @param net the network connection | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int jack_net_slave_deactivate(jack_net_slave_t* net); | |||
| /** | |||
| * Prototype for BufferSize callback. | |||
| * @param nframes buffer size | |||
| * @param arg pointer to a client supplied structure supplied by jack_set_net_buffer_size_callback(). | |||
| * | |||
| * @return zero on success, non-zero on error | |||
| */ | |||
| typedef int (*JackNetSlaveBufferSizeCallback)(jack_nframes_t nframes, void *arg); | |||
| /** | |||
| * Prototype for SampleRate callback | |||
| * @param nframes sample rate | |||
| * @param arg pointer to a client supplied structure supplied by jack_set_net_sample_rate_callback(). | |||
| * | |||
| * @return zero on success, non-zero on error | |||
| */ | |||
| typedef int (*JackNetSlaveSampleRateCallback)(jack_nframes_t nframes, void *arg); | |||
| /** | |||
| * Set network buffer size callback. | |||
| * @param net the network connection | |||
| * @param bufsize_callback the buffer size callback | |||
| * @param arg pointer to a client supplied structure | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg); | |||
| /** | |||
| * Set network sample rate callback. | |||
| * @param net the network connection | |||
| * @param samplerate_callback the sample rate callback | |||
| * @param arg pointer to a client supplied structure | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg); | |||
| /** | |||
| * Prototype for server Shutdown callback (if not set, the client will just restart, waiting for an available master again.) | |||
| * @param arg pointer to a client supplied structure supplied by jack_set_net_shutdown_callback(). | |||
| */ | |||
| typedef void (*JackNetSlaveShutdownCallback)(void* data); | |||
| /** | |||
| * Set network shutdown callback. | |||
| * @param net the network connection | |||
| * @param shutdown_callback the shutdown callback | |||
| * @param arg pointer to a client supplied structure | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg); | |||
| /** | |||
| * jack_net_t is an opaque type. You may only access it using the | |||
| * API provided. | |||
| */ | |||
| typedef struct _jack_net_master jack_net_master_t; | |||
| /** | |||
| * Open a network connection with the slave machine. | |||
| * @param ip the multicast address of the master | |||
| * @param port the connection port | |||
| * @param request a connection request structure | |||
| * @param result a connection result structure | |||
| * | |||
| * @return Opaque net handle if successful or NULL in case of error. | |||
| */ | |||
| jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* name, jack_master_t* request, jack_slave_t* result); | |||
| /** | |||
| * Close the network connection with the master machine. | |||
| * @param net the network connection to be closed | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int jack_net_master_close(jack_net_master_t* net); | |||
| /** | |||
| * Receive sync and data from the network | |||
| * @param net the network connection | |||
| * @param audio_input number of audio inputs | |||
| * @param audio_input_buffer an array of audio input buffers | |||
| * @param midi_input number of MIDI inputs | |||
| * @param midi_input_buffer an array of MIDI input buffers | |||
| * | |||
| * @return zero on success, non-zero on error | |||
| */ | |||
| int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer); | |||
| /** | |||
| * Send sync and data to the network | |||
| * @param net the network connection | |||
| * @param audio_output number of audio outputs | |||
| * @param audio_output_buffer an array of audio output buffers | |||
| * @param midi_output number of MIDI ouputs | |||
| * @param midi_output_buffer an array of MIDI output buffers | |||
| * | |||
| * @return zero on success, non-zero on error | |||
| */ | |||
| int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer); | |||
| // Experimental Adapter API | |||
| /** | |||
| * jack_adapter_t is an opaque type. You may only access it using the | |||
| * API provided. | |||
| */ | |||
| typedef struct _jack_adapter jack_adapter_t; | |||
| /** | |||
| * Create an adapter. | |||
| * @param input number of audio inputs | |||
| * @param output of audio outputs | |||
| * @param host_buffer_size the host buffer size in frames | |||
| * @param host_sample_rate the host buffer sample rate | |||
| * @param adapted_buffer_size the adapted buffer size in frames | |||
| * @param adapted_sample_rate the adapted buffer sample rate | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| jack_adapter_t* jack_create_adapter(int input, int output, | |||
| jack_nframes_t host_buffer_size, | |||
| jack_nframes_t host_sample_rate, | |||
| jack_nframes_t adapted_buffer_size, | |||
| jack_nframes_t adapted_sample_rate); | |||
| /** | |||
| * Destroy an adapter. | |||
| * @param adapter the adapter to be destroyed | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int jack_destroy_adapter(jack_adapter_t* adapter); | |||
| /** | |||
| * Flush internal state of an adapter. | |||
| * @param adapter the adapter to be flushed | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| void jack_flush_adapter(jack_adapter_t* adapter); | |||
| /** | |||
| * Push input to and pull output from adapter ringbuffer | |||
| * @param adapter the adapter | |||
| * @param input an array of audio input buffers | |||
| * @param output an array of audio ouput buffers | |||
| * @param frames number of frames | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); | |||
| /** | |||
| * Pull input to and push output from adapter ringbuffer | |||
| * @param adapter the adapter | |||
| * @param input an array of audio input buffers | |||
| * @param output an array of audio ouput buffers | |||
| * @param frames number of frames | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __net_h__ */ | |||
| @@ -59,7 +59,7 @@ EXPORT void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz); | |||
| EXPORT size_t jack_ringbuffer_write(jack_ringbuffer_t *rb, const char *src, | |||
| size_t cnt); | |||
| void jack_ringbuffer_write_advance(jack_ringbuffer_t *rb, size_t cnt); | |||
| size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb); | |||
| size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb); | |||
| /* Create a new ringbuffer to hold at least `sz' bytes of data. The | |||
| actual buffer size is rounded up to the next power of two. */ | |||
| @@ -69,13 +69,13 @@ jack_ringbuffer_create (size_t sz) | |||
| { | |||
| int power_of_two; | |||
| jack_ringbuffer_t *rb; | |||
| if ((rb = (jack_ringbuffer_t *) malloc (sizeof (jack_ringbuffer_t))) == NULL) { | |||
| return NULL; | |||
| } | |||
| for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++); | |||
| rb->size = 1 << power_of_two; | |||
| rb->size_mask = rb->size; | |||
| rb->size_mask -= 1; | |||
| @@ -86,7 +86,7 @@ jack_ringbuffer_create (size_t sz) | |||
| return NULL; | |||
| } | |||
| rb->mlocked = 0; | |||
| return rb; | |||
| } | |||
| @@ -126,6 +126,7 @@ jack_ringbuffer_reset (jack_ringbuffer_t * rb) | |||
| { | |||
| rb->read_ptr = 0; | |||
| rb->write_ptr = 0; | |||
| memset(rb->buf, 0, rb->size); | |||
| } | |||
| /* Reset the read and write pointers to zero. This is not thread | |||
| @@ -149,10 +150,10 @@ EXPORT size_t | |||
| jack_ringbuffer_read_space (const jack_ringbuffer_t * rb) | |||
| { | |||
| size_t w, r; | |||
| w = rb->write_ptr; | |||
| r = rb->read_ptr; | |||
| if (w > r) { | |||
| return w - r; | |||
| } else { | |||
| @@ -219,8 +220,8 @@ jack_ringbuffer_read (jack_ringbuffer_t * rb, char *dest, size_t cnt) | |||
| return to_read; | |||
| } | |||
| /* The copying data reader w/o read pointer advance. Copy at most | |||
| `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes | |||
| /* The copying data reader w/o read pointer advance. Copy at most | |||
| `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes | |||
| copied. */ | |||
| EXPORT size_t | |||
| @@ -186,6 +186,38 @@ def build(bld): | |||
| if bld.env['IS_SUN']: | |||
| serverlib.env.append_value("LINKFLAGS", "-lnsl -lsocket") | |||
| netlib = bld.new_task_gen('cxx', 'shlib') | |||
| netlib.features.append('cc') | |||
| netlib.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] | |||
| netlib.includes = includes | |||
| netlib.name = 'netlib' | |||
| netlib.target = 'jacknet' | |||
| netlib.uselib = 'SAMPLERATE' | |||
| netlib.install_path = '${LIBDIR}' | |||
| netlib.source = ['JackNetAPI.cpp', | |||
| 'JackNetInterface.cpp', | |||
| 'JackNetTool.cpp', | |||
| 'JackAudioAdapterInterface.cpp', | |||
| 'JackLibSampleRateResampler.cpp', | |||
| 'JackResampler.cpp', | |||
| 'JackGlobals.cpp', | |||
| 'ringbuffer.c'] | |||
| if bld.env['IS_LINUX']: | |||
| netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../linux/JackLinuxTime.c'] | |||
| netlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") | |||
| if bld.env['IS_SUN']: | |||
| netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../solaris/JackSolarisTime.c'] | |||
| netlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") | |||
| if bld.env['IS_MACOSX']: | |||
| netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../macosx/JackMachThread.cpp', '../macosx/JackMachTime.c'] | |||
| netlib.env.append_value("LINKFLAGS", "-framework CoreAudio -single_module") | |||
| netlib.vnum = bld.env['JACK_API_VERSION'] | |||
| clientlib = bld.new_task_gen('cxx', 'shlib') | |||
| clientlib.features.append('cc') | |||
| clientlib.defines = 'HAVE_CONFIG_H' | |||
| @@ -0,0 +1,181 @@ | |||
| /* | |||
| Copyright (C) 2009 Grame | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 of the License, or | |||
| (at your option) any later version. | |||
| This program is distributed in the hope that it will be useful, | |||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <errno.h> | |||
| #ifndef WIN32 | |||
| #include <unistd.h> | |||
| #endif | |||
| #include <math.h> | |||
| #include <signal.h> | |||
| #include <getopt.h> | |||
| #include <string.h> | |||
| #include <jack/net.h> | |||
| jack_net_master_t* net; | |||
| #define BUFFER_SIZE 512 | |||
| #define SAMPLE_RATE 44100 | |||
| static void signal_handler(int sig) | |||
| { | |||
| jack_net_master_close(net); | |||
| fprintf(stderr, "signal received, exiting ...\n"); | |||
| exit(0); | |||
| } | |||
| static void | |||
| usage () | |||
| { | |||
| fprintf (stderr, "\n" | |||
| "usage: jack_net_master \n" | |||
| " [ -b buffer size (default = %d) ]\n" | |||
| " [ -r sample rate (default = %d) ]\n" | |||
| " [ -a hostname (default = %s) ]\n" | |||
| " [ -p port (default = %d) ]\n", BUFFER_SIZE, SAMPLE_RATE, DEFAULT_MULTICAST_IP, DEFAULT_PORT); | |||
| } | |||
| int | |||
| main (int argc, char *argv[]) | |||
| { | |||
| int buffer_size = BUFFER_SIZE; | |||
| int sample_rate = SAMPLE_RATE; | |||
| int port = DEFAULT_PORT; | |||
| char* multicast_ip = DEFAULT_MULTICAST_IP; | |||
| const char *options = "b:r:a:p:"; | |||
| int option_index; | |||
| int opt; | |||
| struct option long_options[] = | |||
| { | |||
| {"buffer size", 1, 0, 'b'}, | |||
| {"sample rate", 1, 0, 'r'}, | |||
| {"hostname", 1, 0, 'a'}, | |||
| {"port", 1, 0, 'p'}, | |||
| {0, 0, 0, 0} | |||
| }; | |||
| while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { | |||
| switch (opt) { | |||
| case 'b': | |||
| buffer_size = atoi(optarg); | |||
| break; | |||
| case 'r': | |||
| sample_rate = atoi(optarg); | |||
| break; | |||
| case 'a': | |||
| multicast_ip = strdup(optarg); | |||
| break; | |||
| case 'p': | |||
| port = atoi(optarg); | |||
| break; | |||
| case 'h': | |||
| usage(); | |||
| return -1; | |||
| } | |||
| } | |||
| int i; | |||
| jack_master_t request = { buffer_size, sample_rate, "master" }; | |||
| jack_slave_t result; | |||
| float** audio_input_buffer; | |||
| float** audio_output_buffer; | |||
| int wait_usec = (int) ((((float)buffer_size) * 1000000) / ((float)sample_rate)); | |||
| printf("Waiting for a slave...\n"); | |||
| if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_master", &request, &result)) == 0) { | |||
| fprintf(stderr, "jack server not running?\n"); | |||
| return 1; | |||
| } | |||
| printf("Slave is running...\n"); | |||
| /* install a signal handler to properly quits jack client */ | |||
| #ifdef WIN32 | |||
| signal(SIGINT, signal_handler); | |||
| signal(SIGABRT, signal_handler); | |||
| signal(SIGTERM, signal_handler); | |||
| #else | |||
| signal(SIGQUIT, signal_handler); | |||
| signal(SIGTERM, signal_handler); | |||
| signal(SIGHUP, signal_handler); | |||
| signal(SIGINT, signal_handler); | |||
| #endif | |||
| // Allocate buffers | |||
| audio_input_buffer = calloc(result.audio_input, sizeof(float*)); | |||
| for (i = 0; i < result.audio_input; i++) { | |||
| audio_input_buffer[i] = calloc(buffer_size, sizeof(float)); | |||
| } | |||
| audio_output_buffer = calloc(result.audio_output, sizeof(float*)); | |||
| for (i = 0; i < result.audio_output; i++) { | |||
| audio_output_buffer[i] = calloc(buffer_size, sizeof(float)); | |||
| } | |||
| /* | |||
| Run until interrupted. | |||
| WARNING !! : this code is given for demonstration purpose. For proper timing bevahiour | |||
| it has to be called in a real-time context (which is *not* the case here...) | |||
| */ | |||
| while (1) { | |||
| // Copy input to output | |||
| for (i = 0; i < result.audio_input; i++) { | |||
| memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); | |||
| } | |||
| if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { | |||
| printf("jack_net_master_send failure, exiting\n"); | |||
| break; | |||
| } | |||
| if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { | |||
| printf("jack_net_master_recv failure, exiting\n"); | |||
| break; | |||
| } | |||
| usleep(wait_usec); | |||
| }; | |||
| // Wait for application end | |||
| jack_net_master_close(net); | |||
| for (i = 0; i < result.audio_input; i++) { | |||
| free(audio_input_buffer[i]); | |||
| } | |||
| free(audio_input_buffer); | |||
| for (i = 0; i < result.audio_output; i++) { | |||
| free(audio_output_buffer[i]); | |||
| } | |||
| free(audio_output_buffer); | |||
| exit (0); | |||
| } | |||
| @@ -0,0 +1,168 @@ | |||
| /* | |||
| Copyright (C) 2009 Grame | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 of the License, or | |||
| (at your option) any later version. | |||
| This program is distributed in the hope that it will be useful, | |||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <errno.h> | |||
| #ifndef WIN32 | |||
| #include <unistd.h> | |||
| #endif | |||
| #include <math.h> | |||
| #include <signal.h> | |||
| #include <getopt.h> | |||
| #include <string.h> | |||
| #include <jack/net.h> | |||
| jack_net_slave_t* net; | |||
| static void signal_handler(int sig) | |||
| { | |||
| jack_net_slave_close(net); | |||
| fprintf(stderr, "signal received, exiting ...\n"); | |||
| exit(0); | |||
| } | |||
| static void | |||
| usage () | |||
| { | |||
| fprintf (stderr, "\n" | |||
| "usage: jack_net_slave \n" | |||
| " [ -C capture channels (default = 2)]\n" | |||
| " [ -P playback channels (default = 2) ]\n" | |||
| " [ -a hostname (default = %s) ]\n" | |||
| " [ -p port (default = %d)]\n", DEFAULT_MULTICAST_IP, DEFAULT_PORT); | |||
| } | |||
| static void net_shutdown(void* data) | |||
| { | |||
| printf("Restarting...\n"); | |||
| } | |||
| static int net_process(jack_nframes_t buffer_size, | |||
| int audio_input, | |||
| float** audio_input_buffer, | |||
| int midi_input, | |||
| void** midi_input_buffer, | |||
| int audio_output, | |||
| float** audio_output_buffer, | |||
| int midi_output, | |||
| void** midi_output_buffer, | |||
| void* data) | |||
| { | |||
| int i; | |||
| // Copy input to output | |||
| for (i = 0; i < audio_input; i++) { | |||
| memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); | |||
| } | |||
| return 0; | |||
| } | |||
| int | |||
| main (int argc, char *argv[]) | |||
| { | |||
| int audio_input = 2; | |||
| int audio_output = 2; | |||
| int port = DEFAULT_PORT; | |||
| char* multicast_ip = DEFAULT_MULTICAST_IP; | |||
| const char *options = "C:P:a:p:"; | |||
| int option_index; | |||
| int opt; | |||
| struct option long_options[] = | |||
| { | |||
| {"audio input", 1, 0, 'C'}, | |||
| {"audio output", 1, 0, 'P'}, | |||
| {"hostname", 1, 0, 'a'}, | |||
| {"port", 1, 0, 'p'}, | |||
| {0, 0, 0, 0} | |||
| }; | |||
| while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { | |||
| switch (opt) { | |||
| case 'C': | |||
| audio_input = atoi(optarg); | |||
| break; | |||
| case 'P': | |||
| audio_output = atoi(optarg); | |||
| break; | |||
| case 'a': | |||
| multicast_ip = strdup(optarg); | |||
| break; | |||
| case 'p': | |||
| port = atoi(optarg); | |||
| break; | |||
| case 'h': | |||
| usage(); | |||
| return -1; | |||
| } | |||
| } | |||
| jack_slave_t request = { audio_input, audio_output, 0, 0, DEFAULT_MTU, -1, JackSlowMode }; | |||
| jack_master_t result; | |||
| printf("Waiting for a master...\n"); | |||
| if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_slave", &request, &result)) == 0) { | |||
| fprintf(stderr, "jack server not running?\n"); | |||
| return 1; | |||
| } | |||
| printf("Slave is found and running...\n"); | |||
| jack_set_net_slave_process_callback(net, net_process, NULL); | |||
| jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL); | |||
| if (jack_net_slave_activate(net) != 0) { | |||
| fprintf(stderr, "Cannot sactivate client\n"); | |||
| return 1; | |||
| } | |||
| /* install a signal handler to properly quits jack client */ | |||
| #ifdef WIN32 | |||
| signal(SIGINT, signal_handler); | |||
| signal(SIGABRT, signal_handler); | |||
| signal(SIGTERM, signal_handler); | |||
| #else | |||
| signal(SIGQUIT, signal_handler); | |||
| signal(SIGTERM, signal_handler); | |||
| signal(SIGHUP, signal_handler); | |||
| signal(SIGINT, signal_handler); | |||
| #endif | |||
| /* run until interrupted */ | |||
| while (1) { | |||
| #ifdef WIN32 | |||
| Sleep(1000); | |||
| #else | |||
| sleep(1); | |||
| #endif | |||
| }; | |||
| // Wait for application end | |||
| jack_net_slave_deactivate(net); | |||
| jack_net_slave_close(net); | |||
| exit (0); | |||
| } | |||
| @@ -25,6 +25,8 @@ example_programs = { | |||
| 'jack_simple_session_client' : 'simple_session_client.c', | |||
| 'jack_session_notify' : 'session_notify.c', | |||
| 'jack_server_control' : 'server_control.cpp', | |||
| 'jack_net_slave' : 'netslave.c', | |||
| 'jack_net_master' : 'netmaster.c', | |||
| 'jack_latent_client' : 'latent_client.c', | |||
| 'jack_midi_dump' : 'midi_dump.c', | |||
| 'jack_midi_latency_test' : 'midi_latency_test.c' | |||
| @@ -86,8 +88,13 @@ def build(bld): | |||
| prog.env.append_value("LINKFLAGS", "-lm") | |||
| if example_program == 'jack_server_control': | |||
| prog.uselib_local = 'serverlib' | |||
| elif example_program == 'jack_net_slave': | |||
| prog.uselib_local = 'netlib' | |||
| elif example_program == 'jack_net_master': | |||
| prog.uselib_local = 'netlib' | |||
| else: | |||
| prog.uselib_local = 'clientlib' | |||
| prog.uselib_local = 'clientlib' | |||
| prog.target = example_program | |||
| if bld.env['BUILD_EXAMPLE_CLIENT_TRANSPORT']: | |||
| @@ -18,9 +18,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| #include "JackMachThread.h" | |||
| #include "JackError.h" | |||
| #include "/Developer/Extras/CoreAudio/PublicUtility/CAHostTimeBase.h" | |||
| namespace Jack | |||
| { | |||
| @@ -30,11 +33,17 @@ int JackMachThread::SetThreadToPriority(jack_native_thread_t thread, UInt32 inPr | |||
| // REAL-TIME / TIME-CONSTRAINT THREAD | |||
| thread_time_constraint_policy_data_t theTCPolicy; | |||
| #ifdef MY_TARGET_OS_IPHONE | |||
| theTCPolicy.period = CAHostTimeBase::ConvertFromNanos(period); | |||
| theTCPolicy.computation = CAHostTimeBase::ConvertFromNanos(computation); | |||
| theTCPolicy.constraint = CAHostTimeBase::ConvertFromNanos(constraint); | |||
| #else | |||
| theTCPolicy.period = AudioConvertNanosToHostTime(period); | |||
| theTCPolicy.computation = AudioConvertNanosToHostTime(computation); | |||
| theTCPolicy.constraint = AudioConvertNanosToHostTime(constraint); | |||
| #endif | |||
| theTCPolicy.preemptible = true; | |||
| kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t) & theTCPolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT); | |||
| kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t) &theTCPolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT); | |||
| jack_log("JackMachThread::thread_policy_set res = %ld", res); | |||
| return (res == KERN_SUCCESS) ? 0 : -1; | |||
| } else { | |||
| @@ -57,7 +66,7 @@ int JackMachThread::SetThreadToPriority(jack_native_thread_t thread, UInt32 inPr | |||
| relativePriority = inPriority - GetThreadSetPriority(pthread_self()); | |||
| thePrecedencePolicy.importance = relativePriority; | |||
| kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_PRECEDENCE_POLICY, (thread_policy_t) & thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT); | |||
| kern_return_t res = thread_policy_set(pthread_mach_thread_np(thread), THREAD_PRECEDENCE_POLICY, (thread_policy_t) &thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT); | |||
| jack_log("JackMachThread::thread_policy_set res = %ld", res); | |||
| return (res == KERN_SUCCESS) ? 0 : -1; | |||
| } | |||
| @@ -130,9 +139,16 @@ int JackMachThread::GetParams(jack_native_thread_t thread, UInt64* period, UInt6 | |||
| &count, | |||
| &get_default); | |||
| if (res == KERN_SUCCESS) { | |||
| #ifdef MY_TARGET_OS_IPHONE | |||
| *period = CAHostTimeBase::ConvertToNanos(theTCPolicy.period); | |||
| *computation = CAHostTimeBase::ConvertToNanos(theTCPolicy.computation); | |||
| *constraint = CAHostTimeBase::ConvertToNanos(theTCPolicy.constraint); | |||
| #else | |||
| *period = AudioConvertHostTimeToNanos(theTCPolicy.period); | |||
| *computation = AudioConvertHostTimeToNanos(theTCPolicy.computation); | |||
| *constraint = AudioConvertHostTimeToNanos(theTCPolicy.constraint); | |||
| #endif | |||
| jack_log("JackMachThread::GetParams period = %ld computation = %ld constraint = %ld", long(*period / 1000.0f), long(*computation / 1000.0f), long(*constraint / 1000.0f)); | |||
| return 0; | |||
| } else { | |||
| @@ -61,12 +61,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| #ifndef __JackMachThread__ | |||
| #define __JackMachThread__ | |||
| #include <TargetConditionals.h> | |||
| #ifdef MY_TARGET_OS_IPHONE | |||
| typedef unsigned char Boolean; | |||
| #endif | |||
| #include "JackPosixThread.h" | |||
| #ifndef MY_TARGET_OS_IPHONE | |||
| #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> | |||
| #endif | |||
| #include <mach/thread_policy.h> | |||
| #include <mach/thread_act.h> | |||
| #ifndef MY_TARGET_OS_IPHONE | |||
| #include <CoreAudio/HostTime.h> | |||
| #endif | |||
| #define THREAD_SET_PRIORITY 0 | |||
| #define THREAD_SCHEDULED_PRIORITY 1 | |||
| @@ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU Lesser General Public License for more details. | |||
| You should have received a copy of the GNU Lesser General Public License | |||
| along with this program; if not, write to the Free Software | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| @@ -20,25 +20,34 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| #ifndef __JackPlatformPlug_APPLE__ | |||
| #define __JackPlatformPlug_APPLE__ | |||
| #include <TargetConditionals.h> | |||
| #define jack_server_dir "/tmp" | |||
| #define jack_client_dir "/tmp" | |||
| #define JACK_DEFAULT_DRIVER "coreaudio" | |||
| namespace Jack | |||
| { | |||
| { | |||
| struct JackRequest; | |||
| struct JackResult; | |||
| class JackPosixMutex; | |||
| class JackMachThread; | |||
| class JackMachSemaphore; | |||
| class JackSocketServerChannel; | |||
| class JackSocketClientChannel; | |||
| class JackSocketServerNotifyChannel; | |||
| class JackSocketNotifyChannel; | |||
| class JackNetUnixSocket; | |||
| #ifdef MY_TARGET_OS_IPHONE | |||
| class JackClient; | |||
| class JackGraphManager; | |||
| class JackEngineControl; | |||
| class JackSynchro; | |||
| #endif | |||
| } | |||
| /* __JackPlatformMutex__ */ | |||
| @@ -50,8 +59,13 @@ namespace Jack { typedef JackPosixMutex JackMutex; } | |||
| namespace Jack { typedef JackMachThread JackThread; } | |||
| /* __JackPlatformSynchro__ client activation */ | |||
| #ifndef MY_TARGET_OS_IPHONE | |||
| #include "JackMachSemaphore.h" | |||
| namespace Jack { typedef JackMachSemaphore JackSynchro; } | |||
| #endif | |||
| #include "JackSocket.h" | |||
| namespace Jack { typedef JackClientSocket JackChannelTransaction; } | |||
| #include "JackSocket.h" | |||
| namespace Jack { typedef JackClientSocket JackChannelTransaction; } | |||
| @@ -60,7 +74,8 @@ namespace Jack { typedef JackClientSocket JackChannelTransaction; } | |||
| #include "JackProcessSync.h" | |||
| /* Only on windows a special JackProcessSync is used. It is directly defined by including JackProcessSync.h here */ | |||
| /* __JackPlatformServerChannel__ */ | |||
| #ifndef MY_TARGET_OS_IPHONE | |||
| /* __JackPlatformServerChannel__ */ | |||
| #include "JackSocketServerChannel.h" | |||
| namespace Jack { typedef JackSocketServerChannel JackServerChannel; } | |||
| @@ -75,6 +90,7 @@ namespace Jack { typedef JackSocketServerNotifyChannel JackServerNotifyChannel; | |||
| /* __JackPlatformNotifyChannel__ */ | |||
| #include "JackSocketNotifyChannel.h" | |||
| namespace Jack { typedef JackSocketNotifyChannel JackNotifyChannel; } | |||
| #endif | |||
| /* __JackPlatformNetSocket__ */ | |||
| #include "JackNetUnixSocket.h" | |||
| @@ -9506,6 +9506,7 @@ | |||
| ); | |||
| OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; | |||
| OTHER_LDFLAGS = ( | |||
| libcelt.a, | |||
| "-framework", | |||
| Carbon, | |||
| "-framework", | |||
| @@ -9574,6 +9575,7 @@ | |||
| OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; | |||
| OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; | |||
| OTHER_LDFLAGS = ( | |||
| libcelt.a, | |||
| "-framework", | |||
| Carbon, | |||
| "-framework", | |||
| @@ -136,7 +136,7 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface | |||
| public: | |||
| JackCoreAudioAdapter( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); | |||
| JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); | |||
| ~JackCoreAudioAdapter() | |||
| {} | |||
| @@ -0,0 +1,409 @@ | |||
| /* | |||
| Copyright (C) 2010 Grame | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 of the License, or | |||
| (at your option) any later version. | |||
| This program is distributed in the hope that it will be useful, | |||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include "TiPhoneCoreAudioRenderer.h" | |||
| static void PrintStreamDesc(AudioStreamBasicDescription *inDesc) | |||
| { | |||
| printf("- - - - - - - - - - - - - - - - - - - -\n"); | |||
| printf(" Sample Rate:%f\n", inDesc->mSampleRate); | |||
| printf(" Format ID:%.*s\n", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID); | |||
| printf(" Format Flags:%lX\n", inDesc->mFormatFlags); | |||
| printf(" Bytes per Packet:%ld\n", inDesc->mBytesPerPacket); | |||
| printf(" Frames per Packet:%ld\n", inDesc->mFramesPerPacket); | |||
| printf(" Bytes per Frame:%ld\n", inDesc->mBytesPerFrame); | |||
| printf(" Channels per Frame:%ld\n", inDesc->mChannelsPerFrame); | |||
| printf(" Bits per Channel:%ld\n", inDesc->mBitsPerChannel); | |||
| printf("- - - - - - - - - - - - - - - - - - - -\n"); | |||
| } | |||
| static void printError(OSStatus err) | |||
| { | |||
| switch (err) { | |||
| case kAudioConverterErr_FormatNotSupported: | |||
| printf("error code : kAudioConverterErr_FormatNotSupported\n"); | |||
| break; | |||
| case kAudioConverterErr_OperationNotSupported: | |||
| printf("error code : kAudioConverterErr_OperationNotSupported\n"); | |||
| break; | |||
| case kAudioConverterErr_PropertyNotSupported: | |||
| printf("error code : kAudioConverterErr_PropertyNotSupported\n"); | |||
| break; | |||
| case kAudioConverterErr_InvalidInputSize: | |||
| printf("error code : kAudioConverterErr_InvalidInputSize\n"); | |||
| break; | |||
| case kAudioConverterErr_InvalidOutputSize: | |||
| printf("error code : kAudioConverterErr_InvalidOutputSize\n"); | |||
| break; | |||
| case kAudioConverterErr_UnspecifiedError: | |||
| printf("error code : kAudioConverterErr_UnspecifiedError\n"); | |||
| break; | |||
| case kAudioConverterErr_BadPropertySizeError: | |||
| printf("error code : kAudioConverterErr_BadPropertySizeError\n"); | |||
| break; | |||
| case kAudioConverterErr_RequiresPacketDescriptionsError: | |||
| printf("error code : kAudioConverterErr_RequiresPacketDescriptionsError\n"); | |||
| break; | |||
| case kAudioConverterErr_InputSampleRateOutOfRange: | |||
| printf("error code : kAudioConverterErr_InputSampleRateOutOfRange\n"); | |||
| break; | |||
| case kAudioConverterErr_OutputSampleRateOutOfRange: | |||
| printf("error code : kAudioConverterErr_OutputSampleRateOutOfRange\n"); | |||
| break; | |||
| default: | |||
| printf("error code : unknown\n"); | |||
| break; | |||
| } | |||
| } | |||
| OSStatus TiPhoneCoreAudioRenderer::Render(void *inRefCon, | |||
| AudioUnitRenderActionFlags *ioActionFlags, | |||
| const AudioTimeStamp *inTimeStamp, | |||
| UInt32, | |||
| UInt32 inNumberFrames, | |||
| AudioBufferList *ioData) | |||
| { | |||
| TiPhoneCoreAudioRendererPtr renderer = (TiPhoneCoreAudioRendererPtr)inRefCon; | |||
| AudioUnitRender(renderer->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, renderer->fCAInputData); | |||
| float coef = float(LONG_MAX); | |||
| float inv_coef = 1.f/float(LONG_MAX); | |||
| for (int chan = 0; chan < renderer->fDevNumInChans; chan++) { | |||
| for (int frame = 0; frame < inNumberFrames; frame++) { | |||
| renderer->fInChannel[chan][frame] = float(((int*)renderer->fCAInputData->mBuffers[chan].mData)[frame]) * inv_coef; | |||
| } | |||
| } | |||
| renderer->PerformAudioCallback((int)inNumberFrames); | |||
| for (int chan = 0; chan < renderer->fDevNumOutChans; chan++) { | |||
| for (int frame = 0; frame < inNumberFrames; frame++) { | |||
| ((int*)ioData->mBuffers[chan].mData)[frame] = int(renderer->fOutChannel[chan][frame] * coef); | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| void TiPhoneCoreAudioRenderer::InterruptionListener(void *inClientData, UInt32 inInterruption) | |||
| { | |||
| TiPhoneCoreAudioRenderer *obj = (TiPhoneCoreAudioRenderer*)inClientData; | |||
| printf("Session interrupted! --- %s ---", inInterruption == kAudioSessionBeginInterruption ? "Begin Interruption" : "End Interruption"); | |||
| if (inInterruption == kAudioSessionEndInterruption) { | |||
| // make sure we are again the active session | |||
| AudioSessionSetActive(true); | |||
| AudioOutputUnitStart(obj->fAUHAL); | |||
| } | |||
| if (inInterruption == kAudioSessionBeginInterruption) { | |||
| AudioOutputUnitStop(obj->fAUHAL); | |||
| } | |||
| } | |||
| int TiPhoneCoreAudioRenderer::Open(int bufferSize, int samplerate) | |||
| { | |||
| OSStatus err1; | |||
| UInt32 outSize; | |||
| UInt32 enableIO; | |||
| AudioStreamBasicDescription srcFormat, dstFormat; | |||
| printf("Open fDevNumInChans = %ld fDevNumOutChans = %ld bufferSize = %ld samplerate = %ld\n", fDevNumInChans, fDevNumOutChans, bufferSize, samplerate); | |||
| // Initialize and configure the audio session | |||
| err1 = AudioSessionInitialize(NULL, NULL, InterruptionListener, this); | |||
| if (err1 != noErr) { | |||
| printf("Couldn't initialize audio session\n"); | |||
| printError(err1); | |||
| return OPEN_ERR; | |||
| } | |||
| err1 = AudioSessionSetActive(true); | |||
| if (err1 != noErr) { | |||
| printf("Couldn't set audio session active\n"); | |||
| printError(err1); | |||
| return OPEN_ERR; | |||
| } | |||
| UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord; | |||
| err1 = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory); | |||
| if (err1 != noErr) { | |||
| printf("Couldn't set audio category\n"); | |||
| printError(err1); | |||
| return OPEN_ERR; | |||
| } | |||
| //err1 = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propListener, self), "couldn't set property listener"); | |||
| Float64 hwSampleRate; | |||
| outSize = sizeof(hwSampleRate); | |||
| err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &outSize, &hwSampleRate); | |||
| if (err1 != noErr) { | |||
| printf("Couldn't get hw sample rate\n"); | |||
| printError(err1); | |||
| return OPEN_ERR; | |||
| } else { | |||
| printf("Get hw sample rate %f\n", hwSampleRate); | |||
| } | |||
| Float32 hwBufferSize; | |||
| outSize = sizeof(hwBufferSize); | |||
| err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration, &outSize, &hwBufferSize); | |||
| if (err1 != noErr) { | |||
| printf("Couldn't get hw buffer duration\n"); | |||
| printError(err1); | |||
| return OPEN_ERR; | |||
| } else { | |||
| printf("Get hw buffer duration %f\n", hwBufferSize); | |||
| } | |||
| UInt32 hwInput; | |||
| outSize = sizeof(hwInput); | |||
| err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &outSize, &hwInput); | |||
| if (err1 != noErr) { | |||
| printf("Couldn't get hw input channels\n"); | |||
| printError(err1); | |||
| return OPEN_ERR; | |||
| } else { | |||
| printf("Get hw input channels %d\n", hwInput); | |||
| } | |||
| UInt32 hwOutput; | |||
| outSize = sizeof(hwOutput); | |||
| err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputNumberChannels, &outSize, &hwOutput); | |||
| if (err1 != noErr) { | |||
| printf("Couldn't get hw output channels\n"); | |||
| printError(err1); | |||
| return OPEN_ERR; | |||
| } else { | |||
| printf("Get hw output channels %d\n", hwOutput); | |||
| } | |||
| Float32 preferredBufferSize = float(bufferSize) / float(samplerate); | |||
| printf("preferredBufferSize %f \n", preferredBufferSize); | |||
| err1 = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize); | |||
| if (err1 != noErr) { | |||
| printf("Couldn't set i/o buffer duration\n"); | |||
| printError(err1); | |||
| return OPEN_ERR; | |||
| } | |||
| Float64 preferredSamplerate = float(samplerate); | |||
| err1 = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareSampleRate, sizeof(preferredSamplerate), &preferredSamplerate); | |||
| if (err1 != noErr) { | |||
| printf("Couldn't set i/o sample rate\n"); | |||
| printError(err1); | |||
| return OPEN_ERR; | |||
| } | |||
| // AUHAL | |||
| AudioComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple, 0, 0}; | |||
| AudioComponent HALOutput = AudioComponentFindNext(NULL, &cd); | |||
| err1 = AudioComponentInstanceNew(HALOutput, &fAUHAL); | |||
| if (err1 != noErr) { | |||
| printf("Error calling OpenAComponent\n"); | |||
| printError(err1); | |||
| goto error; | |||
| } | |||
| enableIO = 1; | |||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); | |||
| if (err1 != noErr) { | |||
| printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output\n"); | |||
| printError(err1); | |||
| goto error; | |||
| } | |||
| enableIO = 1; | |||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO)); | |||
| if (err1 != noErr) { | |||
| printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input\n"); | |||
| printError(err1); | |||
| goto error; | |||
| } | |||
| UInt32 maxFPS; | |||
| outSize = sizeof(maxFPS); | |||
| err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFPS, &outSize); | |||
| if (err1 != noErr) { | |||
| printf("Couldn't get kAudioUnitProperty_MaximumFramesPerSlice\n"); | |||
| printError(err1); | |||
| goto error; | |||
| } else { | |||
| printf("Get kAudioUnitProperty_MaximumFramesPerSlice %d\n", maxFPS); | |||
| } | |||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&bufferSize, sizeof(UInt32)); | |||
| if (err1 != noErr) { | |||
| printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n"); | |||
| printError(err1); | |||
| goto error; | |||
| } | |||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&bufferSize, sizeof(UInt32)); | |||
| if (err1 != noErr) { | |||
| printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n"); | |||
| printError(err1); | |||
| goto error; | |||
| } | |||
| err1 = AudioUnitInitialize(fAUHAL); | |||
| if (err1 != noErr) { | |||
| printf("Cannot initialize AUHAL unit\n"); | |||
| printError(err1); | |||
| goto error; | |||
| } | |||
| // Setting format | |||
| if (fDevNumInChans > 0) { | |||
| outSize = sizeof(AudioStreamBasicDescription); | |||
| err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &outSize); | |||
| if (err1 != noErr) { | |||
| printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); | |||
| printError(err1); | |||
| } | |||
| PrintStreamDesc(&srcFormat); | |||
| srcFormat.mFormatID = kAudioFormatLinearPCM; | |||
| srcFormat.mFormatFlags = kAudioFormatFlagsCanonical | kLinearPCMFormatFlagIsNonInterleaved; | |||
| srcFormat.mBytesPerPacket = sizeof(AudioUnitSampleType); | |||
| srcFormat.mFramesPerPacket = 1; | |||
| srcFormat.mBytesPerFrame = sizeof(AudioUnitSampleType); | |||
| srcFormat.mChannelsPerFrame = fDevNumInChans; | |||
| srcFormat.mBitsPerChannel = 32; | |||
| PrintStreamDesc(&srcFormat); | |||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); | |||
| if (err1 != noErr) { | |||
| printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); | |||
| printError(err1); | |||
| } | |||
| } | |||
| if (fDevNumOutChans > 0) { | |||
| outSize = sizeof(AudioStreamBasicDescription); | |||
| err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &outSize); | |||
| if (err1 != noErr) { | |||
| printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input\n"); | |||
| printError(err1); | |||
| } | |||
| PrintStreamDesc(&dstFormat); | |||
| dstFormat.mFormatID = kAudioFormatLinearPCM; | |||
| dstFormat.mFormatFlags = kAudioFormatFlagsCanonical | kLinearPCMFormatFlagIsNonInterleaved; | |||
| dstFormat.mBytesPerPacket = sizeof(AudioUnitSampleType); | |||
| dstFormat.mFramesPerPacket = 1; | |||
| dstFormat.mBytesPerFrame = sizeof(AudioUnitSampleType); | |||
| dstFormat.mChannelsPerFrame = fDevNumOutChans; | |||
| dstFormat.mBitsPerChannel = 32; | |||
| PrintStreamDesc(&dstFormat); | |||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); | |||
| if (err1 != noErr) { | |||
| printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input\n"); | |||
| printError(err1); | |||
| } | |||
| } | |||
| if (fDevNumInChans > 0 && fDevNumOutChans == 0) { | |||
| AURenderCallbackStruct output; | |||
| output.inputProc = Render; | |||
| output.inputProcRefCon = this; | |||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output)); | |||
| if (err1 != noErr) { | |||
| printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1\n"); | |||
| printError(err1); | |||
| goto error; | |||
| } | |||
| } else { | |||
| AURenderCallbackStruct output; | |||
| output.inputProc = Render; | |||
| output.inputProcRefCon = this; | |||
| err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output)); | |||
| if (err1 != noErr) { | |||
| printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0\n"); | |||
| printError(err1); | |||
| goto error; | |||
| } | |||
| } | |||
| // Prepare buffers | |||
| fCAInputData = (AudioBufferList*)malloc(sizeof(UInt32) + fDevNumInChans * sizeof(AudioBuffer)); | |||
| fCAInputData->mNumberBuffers = fDevNumInChans; | |||
| for (int i = 0; i < fDevNumInChans; i++) { | |||
| fCAInputData->mBuffers[i].mNumberChannels = 1; | |||
| fCAInputData->mBuffers[i].mDataByteSize = bufferSize * sizeof(int); | |||
| fCAInputData->mBuffers[i].mData = malloc(bufferSize * sizeof(int)); | |||
| } | |||
| /* | |||
| // Add listeners | |||
| err1 = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback, this); | |||
| if (err != noErr) { | |||
| jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDeviceProcessorOverload"); | |||
| printError(err); | |||
| return -1; | |||
| } | |||
| */ | |||
| return NO_ERR; | |||
| error: | |||
| AudioUnitUninitialize(fAUHAL); | |||
| AudioComponentInstanceDispose(fAUHAL); | |||
| return OPEN_ERR; | |||
| } | |||
| int TiPhoneCoreAudioRenderer::Close() | |||
| { | |||
| AudioUnitUninitialize(fAUHAL); | |||
| AudioComponentInstanceDispose(fAUHAL); | |||
| return NO_ERR; | |||
| } | |||
| int TiPhoneCoreAudioRenderer::Start() | |||
| { | |||
| AudioSessionSetActive(true); | |||
| OSStatus err = AudioOutputUnitStart(fAUHAL); | |||
| if (err != noErr) { | |||
| printf("Error while opening device : device open error \n"); | |||
| return OPEN_ERR; | |||
| } else { | |||
| return NO_ERR; | |||
| } | |||
| } | |||
| int TiPhoneCoreAudioRenderer::Stop() | |||
| { | |||
| OSStatus err = AudioOutputUnitStop(fAUHAL); | |||
| if (err != noErr) { | |||
| printf("Error while closing device : device close error \n"); | |||
| return OPEN_ERR; | |||
| } else { | |||
| return NO_ERR; | |||
| } | |||
| } | |||
| @@ -0,0 +1,116 @@ | |||
| /* | |||
| Copyright (C) 2010 Grame | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 of the License, or | |||
| (at your option) any later version. | |||
| This program is distributed in the hope that it will be useful, | |||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #ifndef __TiPhoneCoreAudioRenderer__ | |||
| #define __TiPhoneCoreAudioRenderer__ | |||
| #include <AudioToolbox/AudioConverter.h> | |||
| #include <AudioToolbox/AudioServices.h> | |||
| #include <AudioUnit/AudioUnit.h> | |||
| #define MAX_CHANNELS 256 | |||
| #define OPEN_ERR -1 | |||
| #define NO_ERR 0 | |||
| typedef void (*AudioCallback) (int frames, float** inputs, float** outputs, void* arg); | |||
| class TiPhoneCoreAudioRenderer | |||
| { | |||
| private: | |||
| AudioUnit fAUHAL; | |||
| AudioCallback fAudioCallback; | |||
| void* fCallbackArg; | |||
| int fDevNumInChans; | |||
| int fDevNumOutChans; | |||
| AudioBufferList* fCAInputData; | |||
| float* fInChannel[MAX_CHANNELS]; | |||
| float* fOutChannel[MAX_CHANNELS]; | |||
| static OSStatus Render(void *inRefCon, | |||
| AudioUnitRenderActionFlags *ioActionFlags, | |||
| const AudioTimeStamp *inTimeStamp, | |||
| UInt32 inBusNumber, | |||
| UInt32 inNumberFrames, | |||
| AudioBufferList *ioData); | |||
| static void InterruptionListener(void *inClientData, UInt32 inInterruption); | |||
| public: | |||
| TiPhoneCoreAudioRenderer(int input, int output) | |||
| :fAudioCallback(NULL), fCallbackArg(NULL), fDevNumInChans(input), fDevNumOutChans(output), fCAInputData(NULL) | |||
| { | |||
| memset(fInChannel, 0, sizeof(float*) * MAX_CHANNELS); | |||
| memset(fOutChannel, 0, sizeof(float*) * MAX_CHANNELS); | |||
| for (int i = 0; i < fDevNumInChans; i++) { | |||
| fInChannel[i] = new float[8192]; | |||
| } | |||
| for (int i = 0; i < fDevNumOutChans; i++) { | |||
| fOutChannel[i] = new float[8192]; | |||
| } | |||
| } | |||
| virtual ~TiPhoneCoreAudioRenderer() | |||
| { | |||
| for (int i = 0; i < fDevNumInChans; i++) { | |||
| delete[] fInChannel[i]; | |||
| } | |||
| for (int i = 0; i < fDevNumOutChans; i++) { | |||
| delete[] fOutChannel[i]; | |||
| } | |||
| if (fCAInputData) { | |||
| for (int i = 0; i < fDevNumInChans; i++) { | |||
| free(fCAInputData->mBuffers[i].mData); | |||
| } | |||
| free(fCAInputData); | |||
| } | |||
| } | |||
| int Open(int bufferSize, int sampleRate); | |||
| int Close(); | |||
| int Start(); | |||
| int Stop(); | |||
| void SetAudioCallback(AudioCallback callback, void* arg) | |||
| { | |||
| fAudioCallback = callback; | |||
| fCallbackArg = arg; | |||
| } | |||
| void PerformAudioCallback(int frames) | |||
| { | |||
| if (fAudioCallback) | |||
| fAudioCallback(frames, fInChannel, fOutChannel, fCallbackArg); | |||
| } | |||
| }; | |||
| typedef TiPhoneCoreAudioRenderer * TiPhoneCoreAudioRendererPtr; | |||
| #endif | |||
| @@ -0,0 +1,30 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |||
| <plist version="1.0"> | |||
| <dict> | |||
| <key>CFBundleDevelopmentRegion</key> | |||
| <string>English</string> | |||
| <key>CFBundleDisplayName</key> | |||
| <string>${PRODUCT_NAME}</string> | |||
| <key>CFBundleExecutable</key> | |||
| <string>${EXECUTABLE_NAME}</string> | |||
| <key>CFBundleIconFile</key> | |||
| <string></string> | |||
| <key>CFBundleIdentifier</key> | |||
| <string>fr.grame.iGrame.iPhoneFaustNet</string> | |||
| <key>CFBundleInfoDictionaryVersion</key> | |||
| <string>6.0</string> | |||
| <key>CFBundleName</key> | |||
| <string>${PRODUCT_NAME}</string> | |||
| <key>CFBundlePackageType</key> | |||
| <string>APPL</string> | |||
| <key>CFBundleSignature</key> | |||
| <string>????</string> | |||
| <key>CFBundleVersion</key> | |||
| <string>1.0</string> | |||
| <key>LSRequiresIPhoneOS</key> | |||
| <true/> | |||
| <key>NSMainNibFile</key> | |||
| <string>MainWindow</string> | |||
| </dict> | |||
| </plist> | |||
| @@ -0,0 +1,440 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10"> | |||
| <data> | |||
| <int key="IBDocument.SystemTarget">528</int> | |||
| <string key="IBDocument.SystemVersion">10C540</string> | |||
| <string key="IBDocument.InterfaceBuilderVersion">740</string> | |||
| <string key="IBDocument.AppKitVersion">1038.25</string> | |||
| <string key="IBDocument.HIToolboxVersion">458.00</string> | |||
| <object class="NSMutableDictionary" key="IBDocument.PluginVersions"> | |||
| <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string> | |||
| <string key="NS.object.0">62</string> | |||
| </object> | |||
| <object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <integer value="2"/> | |||
| </object> | |||
| <object class="NSArray" key="IBDocument.PluginDependencies"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string> | |||
| </object> | |||
| <object class="NSMutableDictionary" key="IBDocument.Metadata"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <object class="NSArray" key="dict.sortedKeys" id="0"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| </object> | |||
| <object class="NSMutableArray" key="dict.values"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| </object> | |||
| </object> | |||
| <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <object class="IBProxyObject" id="841351856"> | |||
| <string key="IBProxiedObjectIdentifier">IBFilesOwner</string> | |||
| </object> | |||
| <object class="IBProxyObject" id="427554174"> | |||
| <string key="IBProxiedObjectIdentifier">IBFirstResponder</string> | |||
| </object> | |||
| <object class="IBUICustomObject" id="664661524"/> | |||
| <object class="IBUIWindow" id="380026005"> | |||
| <reference key="NSNextResponder"/> | |||
| <int key="NSvFlags">1316</int> | |||
| <object class="NSMutableArray" key="NSSubviews"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <object class="IBUILabel" id="622412730"> | |||
| <reference key="NSNextResponder" ref="380026005"/> | |||
| <int key="NSvFlags">1316</int> | |||
| <string key="NSFrame">{{25, 40}, {267, 21}}</string> | |||
| <reference key="NSSuperview" ref="380026005"/> | |||
| <bool key="IBUIOpaque">NO</bool> | |||
| <bool key="IBUIClipsSubviews">YES</bool> | |||
| <bool key="IBUIUserInteractionEnabled">NO</bool> | |||
| <string key="IBUIText">NetJack : client on JACK server </string> | |||
| <object class="NSFont" key="IBUIFont"> | |||
| <string key="NSName">Helvetica-Bold</string> | |||
| <double key="NSSize">17</double> | |||
| <int key="NSfFlags">16</int> | |||
| </object> | |||
| <object class="NSColor" key="IBUITextColor"> | |||
| <int key="NSColorSpace">1</int> | |||
| <bytes key="NSRGB">MCAwIDAAA</bytes> | |||
| </object> | |||
| <nil key="IBUIHighlightedColor"/> | |||
| <int key="IBUIBaselineAdjustment">1</int> | |||
| <float key="IBUIMinimumFontSize">10</float> | |||
| </object> | |||
| </object> | |||
| <object class="NSPSMatrix" key="NSFrameMatrix"/> | |||
| <string key="NSFrameSize">{320, 480}</string> | |||
| <reference key="NSSuperview"/> | |||
| <object class="NSColor" key="IBUIBackgroundColor"> | |||
| <int key="NSColorSpace">1</int> | |||
| <bytes key="NSRGB">MSAxIDEAA</bytes> | |||
| </object> | |||
| <bool key="IBUIOpaque">NO</bool> | |||
| <bool key="IBUIClearsContextBeforeDrawing">NO</bool> | |||
| <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/> | |||
| </object> | |||
| </object> | |||
| <object class="IBObjectContainer" key="IBDocument.Objects"> | |||
| <object class="NSMutableArray" key="connectionRecords"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <object class="IBConnectionRecord"> | |||
| <object class="IBCocoaTouchOutletConnection" key="connection"> | |||
| <string key="label">delegate</string> | |||
| <reference key="source" ref="841351856"/> | |||
| <reference key="destination" ref="664661524"/> | |||
| </object> | |||
| <int key="connectionID">4</int> | |||
| </object> | |||
| <object class="IBConnectionRecord"> | |||
| <object class="IBCocoaTouchOutletConnection" key="connection"> | |||
| <string key="label">window</string> | |||
| <reference key="source" ref="664661524"/> | |||
| <reference key="destination" ref="380026005"/> | |||
| </object> | |||
| <int key="connectionID">5</int> | |||
| </object> | |||
| </object> | |||
| <object class="IBMutableOrderedSet" key="objectRecords"> | |||
| <object class="NSArray" key="orderedObjects"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <object class="IBObjectRecord"> | |||
| <int key="objectID">0</int> | |||
| <reference key="object" ref="0"/> | |||
| <reference key="children" ref="1000"/> | |||
| <nil key="parent"/> | |||
| </object> | |||
| <object class="IBObjectRecord"> | |||
| <int key="objectID">2</int> | |||
| <reference key="object" ref="380026005"/> | |||
| <object class="NSMutableArray" key="children"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <reference ref="622412730"/> | |||
| </object> | |||
| <reference key="parent" ref="0"/> | |||
| </object> | |||
| <object class="IBObjectRecord"> | |||
| <int key="objectID">-1</int> | |||
| <reference key="object" ref="841351856"/> | |||
| <reference key="parent" ref="0"/> | |||
| <string key="objectName">File's Owner</string> | |||
| </object> | |||
| <object class="IBObjectRecord"> | |||
| <int key="objectID">3</int> | |||
| <reference key="object" ref="664661524"/> | |||
| <reference key="parent" ref="0"/> | |||
| </object> | |||
| <object class="IBObjectRecord"> | |||
| <int key="objectID">-2</int> | |||
| <reference key="object" ref="427554174"/> | |||
| <reference key="parent" ref="0"/> | |||
| </object> | |||
| <object class="IBObjectRecord"> | |||
| <int key="objectID">10</int> | |||
| <reference key="object" ref="622412730"/> | |||
| <reference key="parent" ref="380026005"/> | |||
| </object> | |||
| </object> | |||
| </object> | |||
| <object class="NSMutableDictionary" key="flattenedProperties"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <object class="NSArray" key="dict.sortedKeys"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <string>-1.CustomClassName</string> | |||
| <string>-2.CustomClassName</string> | |||
| <string>10.IBPluginDependency</string> | |||
| <string>2.IBAttributePlaceholdersKey</string> | |||
| <string>2.IBEditorWindowLastContentRect</string> | |||
| <string>2.IBPluginDependency</string> | |||
| <string>2.IBUserGuides</string> | |||
| <string>3.CustomClassName</string> | |||
| <string>3.IBPluginDependency</string> | |||
| </object> | |||
| <object class="NSMutableArray" key="dict.values"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <string>UIApplication</string> | |||
| <string>UIResponder</string> | |||
| <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string> | |||
| <object class="NSMutableDictionary"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <reference key="dict.sortedKeys" ref="0"/> | |||
| <object class="NSMutableArray" key="dict.values"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| </object> | |||
| </object> | |||
| <string>{{366, 320}, {320, 480}}</string> | |||
| <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string> | |||
| <object class="NSMutableArray"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <object class="IBUserGuide"> | |||
| <reference key="view" ref="380026005"/> | |||
| <double key="location">153.5</double> | |||
| <int key="affinity">0</int> | |||
| </object> | |||
| </object> | |||
| <string>iPhoneNetAppDelegate</string> | |||
| <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string> | |||
| </object> | |||
| </object> | |||
| <object class="NSMutableDictionary" key="unlocalizedProperties"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <reference key="dict.sortedKeys" ref="0"/> | |||
| <object class="NSMutableArray" key="dict.values"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| </object> | |||
| </object> | |||
| <nil key="activeLocalization"/> | |||
| <object class="NSMutableDictionary" key="localizations"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <reference key="dict.sortedKeys" ref="0"/> | |||
| <object class="NSMutableArray" key="dict.values"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| </object> | |||
| </object> | |||
| <nil key="sourceID"/> | |||
| <int key="maxID">11</int> | |||
| </object> | |||
| <object class="IBClassDescriber" key="IBDocument.Classes"> | |||
| <object class="NSMutableArray" key="referencedPartialClassDescriptions"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">iPhoneNetAppDelegate</string> | |||
| <string key="superclassName">NSObject</string> | |||
| <object class="NSMutableDictionary" key="outlets"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <object class="NSArray" key="dict.sortedKeys"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <string>navigationController</string> | |||
| <string>window</string> | |||
| </object> | |||
| <object class="NSMutableArray" key="dict.values"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <string>UINavigationController</string> | |||
| <string>UIWindow</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBProjectSource</string> | |||
| <string key="minorKey">iPhoneNetAppDelegate.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">iPhoneNetAppDelegate</string> | |||
| <string key="superclassName">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBUserSource</string> | |||
| <string key="minorKey"/> | |||
| </object> | |||
| </object> | |||
| </object> | |||
| <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+"> | |||
| <bool key="EncodedWithXMLCoder">YES</bool> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSError.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSNetServices.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSObject.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSPort.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSStream.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSThread.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSURL.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">Foundation.framework/Headers/NSXMLParser.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">UIApplication</string> | |||
| <string key="superclassName">UIResponder</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">UIKit.framework/Headers/UIApplication.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">UILabel</string> | |||
| <string key="superclassName">UIView</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">UIKit.framework/Headers/UILabel.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">UINavigationController</string> | |||
| <string key="superclassName">UIViewController</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier" id="325457853"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">UIResponder</string> | |||
| <string key="superclassName">NSObject</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">UISearchBar</string> | |||
| <string key="superclassName">UIView</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">UIView</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">UIKit.framework/Headers/UITextField.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">UIView</string> | |||
| <string key="superclassName">UIResponder</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">UIKit.framework/Headers/UIView.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">UIViewController</string> | |||
| <reference key="sourceIdentifier" ref="325457853"/> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">UIViewController</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">UIViewController</string> | |||
| <string key="superclassName">UIResponder</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string> | |||
| </object> | |||
| </object> | |||
| <object class="IBPartialClassDescription"> | |||
| <string key="className">UIWindow</string> | |||
| <string key="superclassName">UIView</string> | |||
| <object class="IBClassDescriptionSource" key="sourceIdentifier"> | |||
| <string key="majorKey">IBFrameworkSource</string> | |||
| <string key="minorKey">UIKit.framework/Headers/UIWindow.h</string> | |||
| </object> | |||
| </object> | |||
| </object> | |||
| </object> | |||
| <int key="IBDocument.localizationMode">0</int> | |||
| <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies"> | |||
| <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string> | |||
| <integer value="528" key="NS.object.0"/> | |||
| </object> | |||
| <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults"> | |||
| <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string> | |||
| <integer value="544" key="NS.object.0"/> | |||
| </object> | |||
| <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies"> | |||
| <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string> | |||
| <integer value="3000" key="NS.object.0"/> | |||
| </object> | |||
| <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool> | |||
| <string key="IBDocument.LastKnownRelativeProjectPath">iPhoneNet.xcodeproj</string> | |||
| <int key="IBDocument.defaultPropertyAccessControl">3</int> | |||
| <string key="IBCocoaTouchPluginVersion">3.1</string> | |||
| </data> | |||
| </archive> | |||
| @@ -0,0 +1,754 @@ | |||
| //----------------------------------------------------- | |||
| // name: "freeverb" | |||
| // version: "1.0" | |||
| // author: "Grame" | |||
| // license: "BSD" | |||
| // copyright: "(c)GRAME 2006" | |||
| // | |||
| // Code generated with Faust 0.9.9.5b2 (http://faust.grame.fr) | |||
| //----------------------------------------------------- | |||
| /* link with */ | |||
| /* link with */ | |||
| #include <math.h> | |||
| /* link with */ | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include <limits.h> | |||
| #include <math.h> | |||
| #include <errno.h> | |||
| #include <time.h> | |||
| #include <sys/ioctl.h> | |||
| #include <unistd.h> | |||
| #include <fcntl.h> | |||
| #include <pwd.h> | |||
| #include <sys/types.h> | |||
| #include <assert.h> | |||
| #include <pthread.h> | |||
| #include <sys/wait.h> | |||
| #include <libgen.h> | |||
| #include <jack/net.h> | |||
| #include <list> | |||
| #include <vector> | |||
| #include <iostream> | |||
| #include <fstream> | |||
| #include <stack> | |||
| #include <list> | |||
| #include <map> | |||
| #include "JackAudioQueueAdapter.h" | |||
| using namespace std; | |||
| // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero) | |||
| // flags to avoid costly denormals | |||
| #ifdef __SSE__ | |||
| #include <xmmintrin.h> | |||
| #ifdef __SSE2__ | |||
| #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040) | |||
| #else | |||
| #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000) | |||
| #endif | |||
| #else | |||
| #define AVOIDDENORMALS | |||
| #endif | |||
| //#define BENCHMARKMODE | |||
| struct Meta : map<const char*, const char*> | |||
| { | |||
| void declare (const char* key, const char* value) { (*this)[key]=value; } | |||
| }; | |||
| #define max(x,y) (((x)>(y)) ? (x) : (y)) | |||
| #define min(x,y) (((x)<(y)) ? (x) : (y)) | |||
| inline int lsr (int x, int n) { return int(((unsigned int)x) >> n); } | |||
| inline int int2pow2 (int x) { int r=0; while ((1<<r)<x) r++; return r; } | |||
| /****************************************************************************** | |||
| ******************************************************************************* | |||
| VECTOR INTRINSICS | |||
| ******************************************************************************* | |||
| *******************************************************************************/ | |||
| /****************************************************************************** | |||
| ******************************************************************************* | |||
| USER INTERFACE | |||
| ******************************************************************************* | |||
| *******************************************************************************/ | |||
| class UI | |||
| { | |||
| bool fStopped; | |||
| public: | |||
| UI() : fStopped(false) {} | |||
| virtual ~UI() {} | |||
| // -- active widgets | |||
| virtual void addButton(const char* label, float* zone) = 0; | |||
| virtual void addToggleButton(const char* label, float* zone) = 0; | |||
| virtual void addCheckButton(const char* label, float* zone) = 0; | |||
| virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0; | |||
| virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0; | |||
| virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0; | |||
| // -- passive widgets | |||
| virtual void addNumDisplay(const char* label, float* zone, int precision) = 0; | |||
| virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) = 0; | |||
| virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0; | |||
| virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0; | |||
| // -- frames and labels | |||
| virtual void openFrameBox(const char* label) = 0; | |||
| virtual void openTabBox(const char* label) = 0; | |||
| virtual void openHorizontalBox(const char* label) = 0; | |||
| virtual void openVerticalBox(const char* label) = 0; | |||
| virtual void closeBox() = 0; | |||
| virtual void show() = 0; | |||
| virtual void run() = 0; | |||
| void stop() { fStopped = true; } | |||
| bool stopped() { return fStopped; } | |||
| virtual void declare(float* zone, const char* key, const char* value) {} | |||
| }; | |||
| struct param { | |||
| float* fZone; float fMin; float fMax; | |||
| param(float* z, float a, float b) : fZone(z), fMin(a), fMax(b) {} | |||
| }; | |||
| class CMDUI : public UI | |||
| { | |||
| int fArgc; | |||
| char** fArgv; | |||
| stack<string> fPrefix; | |||
| map<string, param> fKeyParam; | |||
| void addOption(const char* label, float* zone, float min, float max) | |||
| { | |||
| string fullname = fPrefix.top() + label; | |||
| fKeyParam.insert(make_pair(fullname, param(zone, min, max))); | |||
| } | |||
| void openAnyBox(const char* label) | |||
| { | |||
| string prefix; | |||
| if (label && label[0]) { | |||
| prefix = fPrefix.top() + "-" + label; | |||
| } else { | |||
| prefix = fPrefix.top(); | |||
| } | |||
| fPrefix.push(prefix); | |||
| } | |||
| public: | |||
| CMDUI(int argc, char *argv[]) : UI(), fArgc(argc), fArgv(argv) { fPrefix.push("--"); } | |||
| virtual ~CMDUI() {} | |||
| virtual void addButton(const char* label, float* zone) {}; | |||
| virtual void addToggleButton(const char* label, float* zone) {}; | |||
| virtual void addCheckButton(const char* label, float* zone) {}; | |||
| virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) | |||
| { | |||
| addOption(label,zone,min,max); | |||
| } | |||
| virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) | |||
| { | |||
| addOption(label,zone,min,max); | |||
| } | |||
| virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) | |||
| { | |||
| addOption(label,zone,min,max); | |||
| } | |||
| // -- passive widgets | |||
| virtual void addNumDisplay(const char* label, float* zone, int precision) {} | |||
| virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) {} | |||
| virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) {} | |||
| virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) {} | |||
| virtual void openFrameBox(const char* label) { openAnyBox(label); } | |||
| virtual void openTabBox(const char* label) { openAnyBox(label); } | |||
| virtual void openHorizontalBox(const char* label) { openAnyBox(label); } | |||
| virtual void openVerticalBox(const char* label) { openAnyBox(label); } | |||
| virtual void closeBox() { fPrefix.pop(); } | |||
| virtual void show() {} | |||
| virtual void run() | |||
| { | |||
| char c; | |||
| printf("Type 'q' to quit\n"); | |||
| while ((c = getchar()) != 'q') { | |||
| sleep(1); | |||
| } | |||
| } | |||
| void print() | |||
| { | |||
| map<string, param>::iterator i; | |||
| cout << fArgc << "\n"; | |||
| cout << fArgv[0] << " option list : "; | |||
| for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) { | |||
| cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] "; | |||
| } | |||
| } | |||
| void process_command() | |||
| { | |||
| map<string, param>::iterator p; | |||
| for (int i = 1; i < fArgc; i++) { | |||
| if (fArgv[i][0] == '-') { | |||
| p = fKeyParam.find(fArgv[i]); | |||
| if (p == fKeyParam.end()) { | |||
| cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; | |||
| print(); | |||
| exit(1); | |||
| } | |||
| char* end; | |||
| *(p->second.fZone) = float(strtod(fArgv[i+1], &end)); | |||
| i++; | |||
| } | |||
| } | |||
| } | |||
| void process_init() | |||
| { | |||
| map<string, param>::iterator p; | |||
| for (int i = 1; i < fArgc; i++) { | |||
| if (fArgv[i][0] == '-') { | |||
| p = fKeyParam.find(fArgv[i]); | |||
| if (p == fKeyParam.end()) { | |||
| cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; | |||
| exit(1); | |||
| } | |||
| char* end; | |||
| *(p->second.fZone) = float(strtod(fArgv[i+1], &end)); | |||
| i++; | |||
| } | |||
| } | |||
| } | |||
| }; | |||
| //---------------------------------------------------------------- | |||
| // Signal processor definition | |||
| //---------------------------------------------------------------- | |||
| class dsp { | |||
| protected: | |||
| int fSamplingFreq; | |||
| public: | |||
| dsp() {} | |||
| virtual ~dsp() {} | |||
| virtual int getNumInputs() = 0; | |||
| virtual int getNumOutputs() = 0; | |||
| virtual void buildUserInterface(UI* interface) = 0; | |||
| virtual void init(int samplingRate) = 0; | |||
| virtual void compute(int len, float** inputs, float** outputs) = 0; | |||
| virtual void conclude() {} | |||
| }; | |||
| //---------------------------------------------------------------------------- | |||
| // FAUST generated code | |||
| //---------------------------------------------------------------------------- | |||
| class mydsp : public dsp { | |||
| private: | |||
| float fslider0; | |||
| float fRec9[2]; | |||
| float fslider1; | |||
| int IOTA; | |||
| float fVec0[2048]; | |||
| float fRec8[2]; | |||
| float fRec11[2]; | |||
| float fVec1[2048]; | |||
| float fRec10[2]; | |||
| float fRec13[2]; | |||
| float fVec2[2048]; | |||
| float fRec12[2]; | |||
| float fRec15[2]; | |||
| float fVec3[2048]; | |||
| float fRec14[2]; | |||
| float fRec17[2]; | |||
| float fVec4[2048]; | |||
| float fRec16[2]; | |||
| float fRec19[2]; | |||
| float fVec5[2048]; | |||
| float fRec18[2]; | |||
| float fRec21[2]; | |||
| float fVec6[2048]; | |||
| float fRec20[2]; | |||
| float fRec23[2]; | |||
| float fVec7[2048]; | |||
| float fRec22[2]; | |||
| float fVec8[1024]; | |||
| float fRec6[2]; | |||
| float fVec9[512]; | |||
| float fRec4[2]; | |||
| float fVec10[512]; | |||
| float fRec2[2]; | |||
| float fVec11[256]; | |||
| float fRec0[2]; | |||
| float fslider2; | |||
| float fRec33[2]; | |||
| float fVec12[2048]; | |||
| float fRec32[2]; | |||
| float fRec35[2]; | |||
| float fVec13[2048]; | |||
| float fRec34[2]; | |||
| float fRec37[2]; | |||
| float fVec14[2048]; | |||
| float fRec36[2]; | |||
| float fRec39[2]; | |||
| float fVec15[2048]; | |||
| float fRec38[2]; | |||
| float fRec41[2]; | |||
| float fVec16[2048]; | |||
| float fRec40[2]; | |||
| float fRec43[2]; | |||
| float fVec17[2048]; | |||
| float fRec42[2]; | |||
| float fRec45[2]; | |||
| float fVec18[2048]; | |||
| float fRec44[2]; | |||
| float fRec47[2]; | |||
| float fVec19[2048]; | |||
| float fRec46[2]; | |||
| float fVec20[1024]; | |||
| float fRec30[2]; | |||
| float fVec21[512]; | |||
| float fRec28[2]; | |||
| float fVec22[512]; | |||
| float fRec26[2]; | |||
| float fVec23[256]; | |||
| float fRec24[2]; | |||
| public: | |||
| static void metadata(Meta* m) { | |||
| m->declare("name", "freeverb"); | |||
| m->declare("version", "1.0"); | |||
| m->declare("author", "Grame"); | |||
| m->declare("license", "BSD"); | |||
| m->declare("copyright", "(c)GRAME 2006"); | |||
| } | |||
| virtual int getNumInputs() { return 2; } | |||
| virtual int getNumOutputs() { return 2; } | |||
| static void classInit(int samplingFreq) { | |||
| } | |||
| virtual void instanceInit(int samplingFreq) { | |||
| fSamplingFreq = samplingFreq; | |||
| fslider0 = 0.5f; | |||
| for (int i=0; i<2; i++) fRec9[i] = 0; | |||
| fslider1 = 0.8f; | |||
| IOTA = 0; | |||
| for (int i=0; i<2048; i++) fVec0[i] = 0; | |||
| for (int i=0; i<2; i++) fRec8[i] = 0; | |||
| for (int i=0; i<2; i++) fRec11[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec1[i] = 0; | |||
| for (int i=0; i<2; i++) fRec10[i] = 0; | |||
| for (int i=0; i<2; i++) fRec13[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec2[i] = 0; | |||
| for (int i=0; i<2; i++) fRec12[i] = 0; | |||
| for (int i=0; i<2; i++) fRec15[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec3[i] = 0; | |||
| for (int i=0; i<2; i++) fRec14[i] = 0; | |||
| for (int i=0; i<2; i++) fRec17[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec4[i] = 0; | |||
| for (int i=0; i<2; i++) fRec16[i] = 0; | |||
| for (int i=0; i<2; i++) fRec19[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec5[i] = 0; | |||
| for (int i=0; i<2; i++) fRec18[i] = 0; | |||
| for (int i=0; i<2; i++) fRec21[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec6[i] = 0; | |||
| for (int i=0; i<2; i++) fRec20[i] = 0; | |||
| for (int i=0; i<2; i++) fRec23[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec7[i] = 0; | |||
| for (int i=0; i<2; i++) fRec22[i] = 0; | |||
| for (int i=0; i<1024; i++) fVec8[i] = 0; | |||
| for (int i=0; i<2; i++) fRec6[i] = 0; | |||
| for (int i=0; i<512; i++) fVec9[i] = 0; | |||
| for (int i=0; i<2; i++) fRec4[i] = 0; | |||
| for (int i=0; i<512; i++) fVec10[i] = 0; | |||
| for (int i=0; i<2; i++) fRec2[i] = 0; | |||
| for (int i=0; i<256; i++) fVec11[i] = 0; | |||
| for (int i=0; i<2; i++) fRec0[i] = 0; | |||
| fslider2 = 0.8f; | |||
| for (int i=0; i<2; i++) fRec33[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec12[i] = 0; | |||
| for (int i=0; i<2; i++) fRec32[i] = 0; | |||
| for (int i=0; i<2; i++) fRec35[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec13[i] = 0; | |||
| for (int i=0; i<2; i++) fRec34[i] = 0; | |||
| for (int i=0; i<2; i++) fRec37[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec14[i] = 0; | |||
| for (int i=0; i<2; i++) fRec36[i] = 0; | |||
| for (int i=0; i<2; i++) fRec39[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec15[i] = 0; | |||
| for (int i=0; i<2; i++) fRec38[i] = 0; | |||
| for (int i=0; i<2; i++) fRec41[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec16[i] = 0; | |||
| for (int i=0; i<2; i++) fRec40[i] = 0; | |||
| for (int i=0; i<2; i++) fRec43[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec17[i] = 0; | |||
| for (int i=0; i<2; i++) fRec42[i] = 0; | |||
| for (int i=0; i<2; i++) fRec45[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec18[i] = 0; | |||
| for (int i=0; i<2; i++) fRec44[i] = 0; | |||
| for (int i=0; i<2; i++) fRec47[i] = 0; | |||
| for (int i=0; i<2048; i++) fVec19[i] = 0; | |||
| for (int i=0; i<2; i++) fRec46[i] = 0; | |||
| for (int i=0; i<1024; i++) fVec20[i] = 0; | |||
| for (int i=0; i<2; i++) fRec30[i] = 0; | |||
| for (int i=0; i<512; i++) fVec21[i] = 0; | |||
| for (int i=0; i<2; i++) fRec28[i] = 0; | |||
| for (int i=0; i<512; i++) fVec22[i] = 0; | |||
| for (int i=0; i<2; i++) fRec26[i] = 0; | |||
| for (int i=0; i<256; i++) fVec23[i] = 0; | |||
| for (int i=0; i<2; i++) fRec24[i] = 0; | |||
| } | |||
| virtual void init(int samplingFreq) { | |||
| classInit(samplingFreq); | |||
| instanceInit(samplingFreq); | |||
| } | |||
| virtual void buildUserInterface(UI* interface) { | |||
| interface->openVerticalBox("Freeverb"); | |||
| interface->addHorizontalSlider("Damp", &fslider0, 0.5f, 0.0f, 1.0f, 2.500000e-02f); | |||
| interface->addHorizontalSlider("RoomSize", &fslider1, 0.8f, 0.0f, 1.0f, 2.500000e-02f); | |||
| interface->addHorizontalSlider("Wet", &fslider2, 0.8f, 0.0f, 1.0f, 2.500000e-02f); | |||
| interface->closeBox(); | |||
| } | |||
| virtual void compute (int count, float** input, float** output) { | |||
| float fSlow0 = (0.4f * fslider0); | |||
| float fSlow1 = (1 - fSlow0); | |||
| float fSlow2 = (0.7f + (0.28f * fslider1)); | |||
| float fSlow3 = fslider2; | |||
| float fSlow4 = (1 - fSlow3); | |||
| float* input0 = input[0]; | |||
| float* input1 = input[1]; | |||
| float* output0 = output[0]; | |||
| float* output1 = output[1]; | |||
| for (int i=0; i<count; i++) { | |||
| fRec9[0] = ((fSlow1 * fRec8[1]) + (fSlow0 * fRec9[1])); | |||
| float fTemp0 = input1[i]; | |||
| float fTemp1 = input0[i]; | |||
| float fTemp2 = (1.500000e-02f * (fTemp1 + fTemp0)); | |||
| fVec0[IOTA&2047] = (fTemp2 + (fSlow2 * fRec9[0])); | |||
| fRec8[0] = fVec0[(IOTA-1617)&2047]; | |||
| fRec11[0] = ((fSlow1 * fRec10[1]) + (fSlow0 * fRec11[1])); | |||
| fVec1[IOTA&2047] = (fTemp2 + (fSlow2 * fRec11[0])); | |||
| fRec10[0] = fVec1[(IOTA-1557)&2047]; | |||
| fRec13[0] = ((fSlow1 * fRec12[1]) + (fSlow0 * fRec13[1])); | |||
| fVec2[IOTA&2047] = (fTemp2 + (fSlow2 * fRec13[0])); | |||
| fRec12[0] = fVec2[(IOTA-1491)&2047]; | |||
| fRec15[0] = ((fSlow1 * fRec14[1]) + (fSlow0 * fRec15[1])); | |||
| fVec3[IOTA&2047] = (fTemp2 + (fSlow2 * fRec15[0])); | |||
| fRec14[0] = fVec3[(IOTA-1422)&2047]; | |||
| fRec17[0] = ((fSlow1 * fRec16[1]) + (fSlow0 * fRec17[1])); | |||
| fVec4[IOTA&2047] = (fTemp2 + (fSlow2 * fRec17[0])); | |||
| fRec16[0] = fVec4[(IOTA-1356)&2047]; | |||
| fRec19[0] = ((fSlow1 * fRec18[1]) + (fSlow0 * fRec19[1])); | |||
| fVec5[IOTA&2047] = (fTemp2 + (fSlow2 * fRec19[0])); | |||
| fRec18[0] = fVec5[(IOTA-1277)&2047]; | |||
| fRec21[0] = ((fSlow1 * fRec20[1]) + (fSlow0 * fRec21[1])); | |||
| fVec6[IOTA&2047] = (fTemp2 + (fSlow2 * fRec21[0])); | |||
| fRec20[0] = fVec6[(IOTA-1188)&2047]; | |||
| fRec23[0] = ((fSlow1 * fRec22[1]) + (fSlow0 * fRec23[1])); | |||
| fVec7[IOTA&2047] = (fTemp2 + (fSlow2 * fRec23[0])); | |||
| fRec22[0] = fVec7[(IOTA-1116)&2047]; | |||
| float fTemp3 = (((((((fRec22[0] + fRec20[0]) + fRec18[0]) + fRec16[0]) + fRec14[0]) + fRec12[0]) + fRec10[0]) + fRec8[0]); | |||
| fVec8[IOTA&1023] = (fTemp3 + (0.5f * fRec6[1])); | |||
| fRec6[0] = fVec8[(IOTA-556)&1023]; | |||
| float fRec7 = (0 - (fTemp3 - fRec6[1])); | |||
| fVec9[IOTA&511] = (fRec7 + (0.5f * fRec4[1])); | |||
| fRec4[0] = fVec9[(IOTA-441)&511]; | |||
| float fRec5 = (fRec4[1] - fRec7); | |||
| fVec10[IOTA&511] = (fRec5 + (0.5f * fRec2[1])); | |||
| fRec2[0] = fVec10[(IOTA-341)&511]; | |||
| float fRec3 = (fRec2[1] - fRec5); | |||
| fVec11[IOTA&255] = (fRec3 + (0.5f * fRec0[1])); | |||
| fRec0[0] = fVec11[(IOTA-225)&255]; | |||
| float fRec1 = (fRec0[1] - fRec3); | |||
| output0[i] = ((fSlow4 * fTemp1) + (fSlow3 * fRec1)); | |||
| fRec33[0] = ((fSlow1 * fRec32[1]) + (fSlow0 * fRec33[1])); | |||
| fVec12[IOTA&2047] = (fTemp2 + (fSlow2 * fRec33[0])); | |||
| fRec32[0] = fVec12[(IOTA-1640)&2047]; | |||
| fRec35[0] = ((fSlow1 * fRec34[1]) + (fSlow0 * fRec35[1])); | |||
| fVec13[IOTA&2047] = (fTemp2 + (fSlow2 * fRec35[0])); | |||
| fRec34[0] = fVec13[(IOTA-1580)&2047]; | |||
| fRec37[0] = ((fSlow1 * fRec36[1]) + (fSlow0 * fRec37[1])); | |||
| fVec14[IOTA&2047] = (fTemp2 + (fSlow2 * fRec37[0])); | |||
| fRec36[0] = fVec14[(IOTA-1514)&2047]; | |||
| fRec39[0] = ((fSlow1 * fRec38[1]) + (fSlow0 * fRec39[1])); | |||
| fVec15[IOTA&2047] = (fTemp2 + (fSlow2 * fRec39[0])); | |||
| fRec38[0] = fVec15[(IOTA-1445)&2047]; | |||
| fRec41[0] = ((fSlow1 * fRec40[1]) + (fSlow0 * fRec41[1])); | |||
| fVec16[IOTA&2047] = (fTemp2 + (fSlow2 * fRec41[0])); | |||
| fRec40[0] = fVec16[(IOTA-1379)&2047]; | |||
| fRec43[0] = ((fSlow1 * fRec42[1]) + (fSlow0 * fRec43[1])); | |||
| fVec17[IOTA&2047] = (fTemp2 + (fSlow2 * fRec43[0])); | |||
| fRec42[0] = fVec17[(IOTA-1300)&2047]; | |||
| fRec45[0] = ((fSlow1 * fRec44[1]) + (fSlow0 * fRec45[1])); | |||
| fVec18[IOTA&2047] = (fTemp2 + (fSlow2 * fRec45[0])); | |||
| fRec44[0] = fVec18[(IOTA-1211)&2047]; | |||
| fRec47[0] = ((fSlow1 * fRec46[1]) + (fSlow0 * fRec47[1])); | |||
| fVec19[IOTA&2047] = (fTemp2 + (fSlow2 * fRec47[0])); | |||
| fRec46[0] = fVec19[(IOTA-1139)&2047]; | |||
| float fTemp4 = (((((((fRec46[0] + fRec44[0]) + fRec42[0]) + fRec40[0]) + fRec38[0]) + fRec36[0]) + fRec34[0]) + fRec32[0]); | |||
| fVec20[IOTA&1023] = (fTemp4 + (0.5f * fRec30[1])); | |||
| fRec30[0] = fVec20[(IOTA-579)&1023]; | |||
| float fRec31 = (0 - (fTemp4 - fRec30[1])); | |||
| fVec21[IOTA&511] = (fRec31 + (0.5f * fRec28[1])); | |||
| fRec28[0] = fVec21[(IOTA-464)&511]; | |||
| float fRec29 = (fRec28[1] - fRec31); | |||
| fVec22[IOTA&511] = (fRec29 + (0.5f * fRec26[1])); | |||
| fRec26[0] = fVec22[(IOTA-364)&511]; | |||
| float fRec27 = (fRec26[1] - fRec29); | |||
| fVec23[IOTA&255] = (fRec27 + (0.5f * fRec24[1])); | |||
| fRec24[0] = fVec23[(IOTA-248)&255]; | |||
| float fRec25 = (fRec24[1] - fRec27); | |||
| output1[i] = ((fSlow4 * fTemp0) + (fSlow3 * fRec25)); | |||
| // post processing | |||
| fRec24[1] = fRec24[0]; | |||
| fRec26[1] = fRec26[0]; | |||
| fRec28[1] = fRec28[0]; | |||
| fRec30[1] = fRec30[0]; | |||
| fRec46[1] = fRec46[0]; | |||
| fRec47[1] = fRec47[0]; | |||
| fRec44[1] = fRec44[0]; | |||
| fRec45[1] = fRec45[0]; | |||
| fRec42[1] = fRec42[0]; | |||
| fRec43[1] = fRec43[0]; | |||
| fRec40[1] = fRec40[0]; | |||
| fRec41[1] = fRec41[0]; | |||
| fRec38[1] = fRec38[0]; | |||
| fRec39[1] = fRec39[0]; | |||
| fRec36[1] = fRec36[0]; | |||
| fRec37[1] = fRec37[0]; | |||
| fRec34[1] = fRec34[0]; | |||
| fRec35[1] = fRec35[0]; | |||
| fRec32[1] = fRec32[0]; | |||
| fRec33[1] = fRec33[0]; | |||
| fRec0[1] = fRec0[0]; | |||
| fRec2[1] = fRec2[0]; | |||
| fRec4[1] = fRec4[0]; | |||
| fRec6[1] = fRec6[0]; | |||
| fRec22[1] = fRec22[0]; | |||
| fRec23[1] = fRec23[0]; | |||
| fRec20[1] = fRec20[0]; | |||
| fRec21[1] = fRec21[0]; | |||
| fRec18[1] = fRec18[0]; | |||
| fRec19[1] = fRec19[0]; | |||
| fRec16[1] = fRec16[0]; | |||
| fRec17[1] = fRec17[0]; | |||
| fRec14[1] = fRec14[0]; | |||
| fRec15[1] = fRec15[0]; | |||
| fRec12[1] = fRec12[0]; | |||
| fRec13[1] = fRec13[0]; | |||
| fRec10[1] = fRec10[0]; | |||
| fRec11[1] = fRec11[0]; | |||
| fRec8[1] = fRec8[0]; | |||
| IOTA = IOTA+1; | |||
| fRec9[1] = fRec9[0]; | |||
| } | |||
| } | |||
| }; | |||
| mydsp DSP; | |||
| /****************************************************************************** | |||
| ******************************************************************************* | |||
| NETJACK AUDIO INTERFACE | |||
| ******************************************************************************* | |||
| *******************************************************************************/ | |||
| //---------------------------------------------------------------------------- | |||
| // number of input and output channels | |||
| //---------------------------------------------------------------------------- | |||
| int gNumInChans; | |||
| int gNumOutChans; | |||
| //---------------------------------------------------------------------------- | |||
| // Jack Callbacks | |||
| //---------------------------------------------------------------------------- | |||
| static void net_shutdown(void *) | |||
| { | |||
| exit(1); | |||
| } | |||
| #ifdef BENCHMARKMODE | |||
| // mesuring jack performances | |||
| static __inline__ unsigned long long int rdtsc(void) | |||
| { | |||
| unsigned long long int x; | |||
| __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); | |||
| return x; | |||
| } | |||
| #define KSKIP 10 | |||
| #define KMESURE 1024 | |||
| int mesure = 0; | |||
| unsigned long long int starts[KMESURE]; | |||
| unsigned long long int stops [KMESURE]; | |||
| #define STARTMESURE starts[mesure%KMESURE] = rdtsc(); | |||
| #define STOPMESURE stops[mesure%KMESURE] = rdtsc(); mesure = mesure+1; | |||
| void printstats() | |||
| { | |||
| unsigned long long int low, hi, tot; | |||
| low = hi = tot = (stops[KSKIP] - starts[KSKIP]); | |||
| if (mesure < KMESURE) { | |||
| for (int i = KSKIP+1; i<mesure; i++) { | |||
| unsigned long long int m = stops[i] - starts[i]; | |||
| if (m<low) low = m; | |||
| if (m>hi) hi = m; | |||
| tot += m; | |||
| } | |||
| cout << low << ' ' << tot/(mesure-KSKIP) << ' ' << hi << endl; | |||
| } else { | |||
| for (int i = KSKIP+1; i<KMESURE; i++) { | |||
| unsigned long long int m = stops[i] - starts[i]; | |||
| if (m<low) low = m; | |||
| if (m>hi) hi = m; | |||
| tot += m; | |||
| } | |||
| cout << low << ' ' << tot/(KMESURE-KSKIP) << ' ' << hi << endl; | |||
| } | |||
| } | |||
| #else | |||
| #define STARTMESURE | |||
| #define STOPMESURE | |||
| #endif | |||
| static int net_process(jack_nframes_t buffer_size, | |||
| int audio_input, | |||
| float** audio_input_buffer, | |||
| int midi_input, | |||
| void** midi_input_buffer, | |||
| int audio_output, | |||
| float** audio_output_buffer, | |||
| int midi_output, | |||
| void** midi_output_buffer, | |||
| void* data) | |||
| { | |||
| AVOIDDENORMALS; | |||
| STARTMESURE | |||
| DSP.compute(buffer_size, audio_input_buffer, audio_output_buffer); | |||
| STOPMESURE | |||
| return 0; | |||
| } | |||
| /****************************************************************************** | |||
| ******************************************************************************* | |||
| MAIN PLAY THREAD | |||
| ******************************************************************************* | |||
| *******************************************************************************/ | |||
| //------------------------------------------------------------------------- | |||
| // MAIN | |||
| //------------------------------------------------------------------------- | |||
| #define TEST_MASTER "194.5.49.5" | |||
| int main(int argc, char *argv[]) { | |||
| UI* interface = new CMDUI(argc, argv); | |||
| jack_net_slave_t* net; | |||
| NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; | |||
| //Jack::JackAudioQueueAdapter audio(2, 2, 1024, 44100, NULL); | |||
| gNumInChans = DSP.getNumInputs(); | |||
| gNumOutChans = DSP.getNumOutputs(); | |||
| jack_slave_t request = { gNumInChans, gNumOutChans, 0, 0, DEFAULT_MTU, -1, JackSlowMode }; | |||
| jack_master_t result; | |||
| printf("Network\n"); | |||
| //if (audio.Open() < 0) { | |||
| // fprintf(stderr, "Cannot open audio\n"); | |||
| // return 1; | |||
| //} | |||
| //audio.Start(); | |||
| // Hang around forever... | |||
| //while(1) CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.25, false); | |||
| if ((net = jack_net_slave_open(TEST_MASTER, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { | |||
| fprintf(stderr, "jack remote server not running ?\n"); | |||
| return 1; | |||
| } | |||
| jack_set_net_slave_process_callback(net, net_process, NULL); | |||
| // We want to restart (that is "wait for available master" again) | |||
| //jack_set_net_shutdown_callback(net, net_shutdown, 0); | |||
| DSP.init(result.sample_rate); | |||
| DSP.buildUserInterface(interface); | |||
| if (jack_net_slave_activate(net) != 0) { | |||
| fprintf(stderr, "cannot activate net"); | |||
| return 1; | |||
| } | |||
| int retVal = UIApplicationMain(argc, argv, nil, nil); | |||
| [pool release]; | |||
| // Wait for application end | |||
| jack_net_slave_deactivate(net); | |||
| jack_net_slave_close(net); | |||
| //if (audio.Close() < 0) { | |||
| // fprintf(stderr, "Cannot close audio\n"); | |||
| //} | |||
| return retVal; | |||
| } | |||
| @@ -0,0 +1,23 @@ | |||
| // | |||
| // iPhoneNetAppDelegate.h | |||
| // iPhoneNet | |||
| // | |||
| // Created by Stéphane LETZ on 16/02/09. | |||
| // Copyright Grame 2009. All rights reserved. | |||
| // | |||
| #import <UIKit/UIKit.h> | |||
| @interface iPhoneNetAppDelegate : NSObject <UIApplicationDelegate> { | |||
| // UIWindow *window; | |||
| IBOutlet UIWindow *window; | |||
| IBOutlet UINavigationController *navigationController; | |||
| } | |||
| //@property (nonatomic, retain) IBOutlet UIWindow *window; | |||
| @property (nonatomic, retain) UIWindow *window; | |||
| @property (nonatomic, retain) UINavigationController *navigationController; | |||
| @end | |||
| @@ -0,0 +1,32 @@ | |||
| // | |||
| // iPhoneNetAppDelegate.m | |||
| // iPhoneNet | |||
| // | |||
| // Created by Stéphane LETZ on 16/02/09. | |||
| // Copyright Grame 2009. All rights reserved. | |||
| // | |||
| #import "iPhoneNetAppDelegate.h" | |||
| @implementation iPhoneNetAppDelegate | |||
| @synthesize window, navigationController; | |||
| - (void)applicationDidFinishLaunching:(UIApplication *)application { | |||
| // Override point for customization after application launch | |||
| // add the navigation controller's view to the window | |||
| [window addSubview: navigationController.view]; | |||
| [window makeKeyAndVisible]; | |||
| } | |||
| - (void)dealloc { | |||
| [navigationController release]; | |||
| [window release]; | |||
| [super dealloc]; | |||
| } | |||
| @end | |||
| @@ -0,0 +1,10 @@ | |||
| // | |||
| // Prefix header for all source files of the 'iPhoneNet' target in the 'iPhoneNet' project | |||
| // | |||
| #ifdef __OBJC__ | |||
| #import <Foundation/Foundation.h> | |||
| #import <UIKit/UIKit.h> | |||
| #endif | |||
| #define MY_TARGET_OS_IPHONE 1 | |||
| @@ -0,0 +1,155 @@ | |||
| // | |||
| // main.m | |||
| // iPhoneNet | |||
| // | |||
| // Created by Stéphane LETZ on 16/02/09. | |||
| // Copyright Grame 2009. All rights reserved. | |||
| // | |||
| #import <UIKit/UIKit.h> | |||
| #include <jack/net.h> | |||
| #include "TiPhoneCoreAudioRenderer.h" | |||
| #define NUM_INPUT 2 | |||
| #define NUM_OUTPUT 2 | |||
| jack_net_master_t* net; | |||
| jack_adapter_t* adapter; | |||
| float** audio_input_buffer = NULL; | |||
| float** audio_output_buffer = NULL; | |||
| int buffer_size = 1024; | |||
| int sample_rate = 22050; | |||
| //int sample_rate = 32000; | |||
| jack_master_t request = { buffer_size, sample_rate, "master" }; | |||
| jack_slave_t result; | |||
| static void MixAudio(float** dst, float** src1, float** src2, int channels, int buffer_size) | |||
| { | |||
| for (int chan = 0; chan < channels; chan++) { | |||
| for (int frame = 0; frame < buffer_size; frame++) { | |||
| dst[chan][frame] = src1[chan][frame] + src2[chan][frame]; | |||
| } | |||
| } | |||
| } | |||
| static void MasterAudioCallback(int frames, float** inputs, float** outputs, void* arg) | |||
| { | |||
| int i; | |||
| // Copy from iPod input to network buffers | |||
| for (i = 0; i < result.audio_input; i++) { | |||
| memcpy(audio_input_buffer[i], inputs[i], buffer_size * sizeof(float)); | |||
| } | |||
| /* | |||
| // Copy from network out buffers to network in buffers (audio thru) | |||
| for (i = 0; i < result.audio_input; i++) { | |||
| memcpy(audio_input_buffer[i], audio_output_buffer[i], buffer_size * sizeof(float)); | |||
| } | |||
| */ | |||
| // Mix iPod input and network in buffers to network out buffers | |||
| //MixAudio(audio_input_buffer, inputs, audio_output_buffer, result.audio_input, buffer_size); | |||
| // Send network buffers | |||
| if (jack_net_master_send(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { | |||
| printf("jack_net_master_send error..\n"); | |||
| } | |||
| // Recv network buffers | |||
| if (jack_net_master_recv(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { | |||
| printf("jack_net_master_recv error..\n"); | |||
| } | |||
| // Copy from network buffers to iPod output | |||
| for (i = 0; i < result.audio_output; i++) { | |||
| memcpy(outputs[i], audio_output_buffer[i], buffer_size * sizeof(float)); | |||
| } | |||
| } | |||
| int main(int argc, char *argv[]) { | |||
| NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; | |||
| int i; | |||
| if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { | |||
| printf("jack_net_master_open error..\n"); | |||
| return -1; | |||
| } | |||
| TiPhoneCoreAudioRenderer audio_device(result.audio_input, result.audio_output); | |||
| // Allocate buffers | |||
| if (result.audio_input > 0) { | |||
| audio_input_buffer = (float**)calloc(result.audio_input, sizeof(float*)); | |||
| for (i = 0; i < result.audio_input; i++) { | |||
| audio_input_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); | |||
| } | |||
| } | |||
| if (result.audio_output > 0) { | |||
| audio_output_buffer = (float**)calloc(result.audio_output, sizeof(float*)); | |||
| for (i = 0; i < result.audio_output; i++) { | |||
| audio_output_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); | |||
| } | |||
| } | |||
| if (audio_device.Open(buffer_size, sample_rate) < 0) { | |||
| return -1; | |||
| } | |||
| audio_device.SetAudioCallback(MasterAudioCallback, NULL); | |||
| if (audio_device.Start() < 0) { | |||
| return -1; | |||
| } | |||
| /* | |||
| // Quite brutal way, the application actually does not start completely, the netjack audio processing loop is used instead... | |||
| // Run until interrupted | |||
| int wait_usec = (unsigned long)((((float)buffer_size) / ((float)sample_rate)) * 1000000.0f); | |||
| while (1) { | |||
| // Copy input to output | |||
| for (i = 0; i < result.audio_input; i++) { | |||
| memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); | |||
| } | |||
| if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { | |||
| printf("jack_net_master_send error..\n"); | |||
| } | |||
| if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { | |||
| printf("jack_net_master_recv error..\n"); | |||
| } | |||
| usleep(wait_usec); | |||
| }; | |||
| */ | |||
| int retVal = UIApplicationMain(argc, argv, nil, nil); | |||
| audio_device.Stop(); | |||
| audio_device.Close(); | |||
| // Wait for application end | |||
| jack_net_master_close(net); | |||
| for (i = 0; i < result.audio_input; i++) { | |||
| free(audio_input_buffer[i]); | |||
| } | |||
| free(audio_input_buffer); | |||
| for (i = 0; i < result.audio_output; i++) { | |||
| free(audio_output_buffer[i]); | |||
| } | |||
| free(audio_output_buffer); | |||
| [pool release]; | |||
| return retVal; | |||
| } | |||
| @@ -0,0 +1,113 @@ | |||
| // | |||
| // main.m | |||
| // iPhoneNet | |||
| // | |||
| // Created by Stéphane LETZ on 16/02/09. | |||
| // Copyright Grame 2009. All rights reserved. | |||
| // | |||
| #import <UIKit/UIKit.h> | |||
| #include <jack/net.h> | |||
| #include "TiPhoneCoreAudioRenderer.h" | |||
| #define NUM_INPUT 0 | |||
| #define NUM_OUTPUT 2 | |||
| jack_net_slave_t* net = NULL; | |||
| jack_adapter_t* adapter = NULL; | |||
| int buffer_size; | |||
| int sample_rate; | |||
| static int net_process(jack_nframes_t buffer_size, | |||
| int audio_input, | |||
| float** audio_input_buffer, | |||
| int midi_input, | |||
| void** midi_input_buffer, | |||
| int audio_output, | |||
| float** audio_output_buffer, | |||
| int midi_output, | |||
| void** midi_output_buffer, | |||
| void* data) | |||
| { | |||
| jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size); | |||
| // Process input, produce output | |||
| if (audio_input == audio_output) { | |||
| // Copy net input to net output | |||
| for (int i = 0; i < audio_input; i++) { | |||
| memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| static void net_shutdown(void *arg) | |||
| { | |||
| if (adapter) | |||
| jack_flush_adapter(adapter); | |||
| } | |||
| static void SlaveAudioCallback(int frames, float** inputs, float** outputs, void* arg) | |||
| { | |||
| jack_adapter_push_and_pull(adapter, inputs, outputs, frames); | |||
| } | |||
| //http://www.securityfocus.com/infocus/1884 | |||
| #define WIFI_MTU 1500 | |||
| int main(int argc, char *argv[]) { | |||
| NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; | |||
| jack_slave_t request = { NUM_OUTPUT, NUM_INPUT, 0, 0, WIFI_MTU, -1, JackCeltEncoder, 128, JackSlowMode }; | |||
| jack_master_t result; | |||
| //if ((net = jack_net_slave_open("169.254.112.119", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { | |||
| if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPod", &request, &result)) == 0) { | |||
| printf("jack_net_slave_open error..\n"); | |||
| return -1; | |||
| } | |||
| if ((adapter = jack_create_adapter(NUM_INPUT, | |||
| NUM_OUTPUT, | |||
| result.buffer_size, | |||
| result.sample_rate, | |||
| result.buffer_size, | |||
| result.sample_rate)) == 0) { | |||
| return -1; | |||
| } | |||
| TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); | |||
| jack_set_net_slave_process_callback(net, net_process, NULL); | |||
| jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL); | |||
| if (jack_net_slave_activate(net) != 0) { | |||
| return -1; | |||
| } | |||
| if (audio_device.Open(result.buffer_size, result.sample_rate) < 0) { | |||
| return -1; | |||
| } | |||
| audio_device.SetAudioCallback(SlaveAudioCallback, NULL); | |||
| if (audio_device.Start() < 0) { | |||
| return -1; | |||
| } | |||
| int retVal = UIApplicationMain(argc, argv, nil, nil); | |||
| [pool release]; | |||
| audio_device.Stop(); | |||
| audio_device.Close(); | |||
| // Wait for application end | |||
| jack_net_slave_deactivate(net); | |||
| jack_net_slave_close(net); | |||
| jack_destroy_adapter(adapter); | |||
| return retVal; | |||
| } | |||
| @@ -20,6 +20,7 @@ | |||
| <Project filename="multiple_metro.cbp" /> | |||
| <Project filename="jack_winmme.cbp" /> | |||
| <Project filename="jack_loopback.cbp" /> | |||
| <Project filename="libjacknet.cbp" active="1" /> | |||
| <Project filename="jackd.cbp" /> | |||
| <Project filename="jack_midi_latency_test.cbp" /> | |||
| <Project filename="jack_netadapter.cbp" /> | |||
| @@ -0,0 +1,149 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> | |||
| <CodeBlocks_project_file> | |||
| <FileVersion major="1" minor="6" /> | |||
| <Project> | |||
| <Option title="libjacknet" /> | |||
| <Option pch_mode="2" /> | |||
| <Option compiler="gcc" /> | |||
| <Build> | |||
| <Target title="Win32 Release"> | |||
| <Option output="Release\bin\libjacknet" prefix_auto="1" extension_auto="1" /> | |||
| <Option object_output="Release" /> | |||
| <Option type="3" /> | |||
| <Option compiler="gcc" /> | |||
| <Option createDefFile="1" /> | |||
| <Option createStaticLib="1" /> | |||
| <Compiler> | |||
| <Add option="-O2" /> | |||
| <Add option="-Wall" /> | |||
| <Add option="-DWIN32" /> | |||
| <Add option="-DNDEBUG" /> | |||
| <Add option="-D_WINDOWS" /> | |||
| <Add option="-D_MBCS" /> | |||
| <Add option="-D_USRDLL" /> | |||
| <Add option="-DLIBJACKDMP_EXPORTS" /> | |||
| <Add option="-DREGEX_MALLOC" /> | |||
| <Add option="-DSTDC_HEADERS" /> | |||
| <Add option="-DSERVER_SIDE" /> | |||
| <Add option="-D__SMP__" /> | |||
| <Add directory="." /> | |||
| <Add directory="..\windows" /> | |||
| <Add directory="..\common\jack" /> | |||
| <Add directory="..\common" /> | |||
| </Compiler> | |||
| <Linker> | |||
| <Add directory="Release\bin" /> | |||
| </Linker> | |||
| </Target> | |||
| <Target title="Win32 Debug"> | |||
| <Option output="Debug\bin\libjacknet" prefix_auto="1" extension_auto="1" /> | |||
| <Option object_output="Debug" /> | |||
| <Option type="3" /> | |||
| <Option compiler="gcc" /> | |||
| <Option createDefFile="1" /> | |||
| <Option createStaticLib="1" /> | |||
| <Compiler> | |||
| <Add option="-Wall" /> | |||
| <Add option="-g" /> | |||
| <Add option="-DWIN32" /> | |||
| <Add option="-D_DEBUG" /> | |||
| <Add option="-D_WINDOWS" /> | |||
| <Add option="-D_MBCS" /> | |||
| <Add option="-D_USRDLL" /> | |||
| <Add option="-DLIBJACKDMP_EXPORTS" /> | |||
| <Add option="-DREGEX_MALLOC" /> | |||
| <Add option="-DSTDC_HEADERS" /> | |||
| <Add option="-DSERVER_SIDE" /> | |||
| <Add option="-D__SMP__" /> | |||
| <Add directory="." /> | |||
| <Add directory="..\windows" /> | |||
| <Add directory="..\common\jack" /> | |||
| <Add directory="..\common" /> | |||
| </Compiler> | |||
| <Linker> | |||
| <Add directory="Debug\bin" /> | |||
| </Linker> | |||
| </Target> | |||
| <Target title="Win32 Profiling"> | |||
| <Option output="Release\bin\libjacknet" prefix_auto="1" extension_auto="1" /> | |||
| <Option object_output="Release" /> | |||
| <Option type="3" /> | |||
| <Option compiler="gcc" /> | |||
| <Option createDefFile="1" /> | |||
| <Option createStaticLib="1" /> | |||
| <Compiler> | |||
| <Add option="-O2" /> | |||
| <Add option="-Wall" /> | |||
| <Add option="-DWIN32" /> | |||
| <Add option="-DNDEBUG" /> | |||
| <Add option="-D_WINDOWS" /> | |||
| <Add option="-D_MBCS" /> | |||
| <Add option="-D_USRDLL" /> | |||
| <Add option="-DLIBJACKDMP_EXPORTS" /> | |||
| <Add option="-DREGEX_MALLOC" /> | |||
| <Add option="-DSTDC_HEADERS" /> | |||
| <Add option="-DSERVER_SIDE" /> | |||
| <Add option="-D__SMP__" /> | |||
| <Add option="-DJACK_MONITOR" /> | |||
| <Add directory="." /> | |||
| <Add directory="..\windows" /> | |||
| <Add directory="..\common\jack" /> | |||
| <Add directory="..\common" /> | |||
| </Compiler> | |||
| <Linker> | |||
| <Add directory="Release\bin" /> | |||
| </Linker> | |||
| </Target> | |||
| </Build> | |||
| <Compiler> | |||
| <Add option="-Wall" /> | |||
| <Add directory="." /> | |||
| <Add directory="..\common" /> | |||
| <Add directory="..\common\jack" /> | |||
| </Compiler> | |||
| <Linker> | |||
| <Add library="kernel32" /> | |||
| <Add library="user32" /> | |||
| <Add library="gdi32" /> | |||
| <Add library="winspool" /> | |||
| <Add library="comdlg32" /> | |||
| <Add library="advapi32" /> | |||
| <Add library="shell32" /> | |||
| <Add library="ole32" /> | |||
| <Add library="oleaut32" /> | |||
| <Add library="uuid" /> | |||
| <Add library="odbc32" /> | |||
| <Add library="odbccp32" /> | |||
| <Add library="ws2_32" /> | |||
| <Add library="libsamplerate-0" /> | |||
| </Linker> | |||
| <Unit filename="..\common\JackAudioAdapterInterface.cpp" /> | |||
| <Unit filename="..\common\JackGlobals.cpp" /> | |||
| <Unit filename="..\common\JackLibSampleRateResampler.cpp" /> | |||
| <Unit filename="..\common\JackNetAPI.cpp" /> | |||
| <Unit filename="..\common\JackNetInterface.cpp" /> | |||
| <Unit filename="..\common\JackNetTool.cpp" /> | |||
| <Unit filename="..\common\JackResampler.cpp" /> | |||
| <Unit filename="..\common\ringbuffer.c"> | |||
| <Option compilerVar="CC" /> | |||
| </Unit> | |||
| <Unit filename="JackNetWinSocket.cpp" /> | |||
| <Unit filename="JackWinThread.cpp" /> | |||
| <Unit filename="JackWinTime.c"> | |||
| <Option compilerVar="CC" /> | |||
| </Unit> | |||
| <Unit filename="libjacknet.rc"> | |||
| <Option compilerVar="WINDRES" /> | |||
| </Unit> | |||
| <Extensions> | |||
| <code_completion /> | |||
| <envvars /> | |||
| <debugger /> | |||
| <AutoVersioning> | |||
| <Scheme minor_max="10" build_max="0" rev_max="0" rev_rand_max="10" build_times_to_increment_minor="100" /> | |||
| <Settings autoincrement="0" date_declarations="0" do_auto_increment="0" ask_to_increment="0" language="C++" svn="0" svn_directory="" header_path="version.h" /> | |||
| <Changes_Log show_changes_editor="0" app_title="released version %M.%m.%b of %p" changeslog_path="ChangesLog.txt" /> | |||
| </AutoVersioning> | |||
| </Extensions> | |||
| </Project> | |||
| </CodeBlocks_project_file> | |||
| @@ -0,0 +1,41 @@ | |||
| // Generated by ResEdit 1.4.3 | |||
| // Copyright (C) 2006-2008 | |||
| // http://www.resedit.net | |||
| #include "resource.h" | |||
| #include "afxres.h" | |||
| // | |||
| // Version Information resources | |||
| // | |||
| LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT | |||
| 1 VERSIONINFO | |||
| FILEVERSION 1,9,3,0 | |||
| PRODUCTVERSION 1,9,3,0 | |||
| FILEOS VOS_UNKNOWN | |||
| FILETYPE VFT_DLL | |||
| BEGIN | |||
| BLOCK "StringFileInfo" | |||
| BEGIN | |||
| BLOCK "040c04b0" | |||
| BEGIN | |||
| VALUE "Comments", "\0" | |||
| VALUE "CompanyName", "Grame\0" | |||
| VALUE "FileDescription", "Jack Net library for Windows\0" | |||
| VALUE "FileVersion", "1, 9, 3, 0\0" | |||
| VALUE "InternalName", "libjacknet\0" | |||
| VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" | |||
| VALUE "LegalTrademarks", "\0" | |||
| VALUE "OriginalFilename", "libjacknet.dll\0" | |||
| VALUE "PrivateBuild", "\0" | |||
| VALUE "ProductName", "libjacknet\0" | |||
| VALUE "ProductVersion", "1, 9, 3, 0\0" | |||
| VALUE "SpecialBuild", "\0" | |||
| END | |||
| END | |||
| BLOCK "VarFileInfo" | |||
| BEGIN | |||
| VALUE "Translation", 1036, 1200 | |||
| END | |||
| END | |||