Browse Source

Merge branch 'master' of ssh://repo.or.cz/srv/git/jack2 into newer-midi

tags/1.9.8
Devin Anderson 15 years ago
parent
commit
576fda8cb1
44 changed files with 6983 additions and 627 deletions
  1. +28
    -29
      ChangeLog
  2. +66
    -43
      common/JackAudioAdapterInterface.cpp
  3. +26
    -8
      common/JackAudioAdapterInterface.h
  4. +53
    -53
      common/JackEngineProfiling.cpp
  5. +63
    -53
      common/JackFilters.h
  6. +3
    -3
      common/JackGlobals.h
  7. +1005
    -0
      common/JackNetAPI.cpp
  8. +41
    -23
      common/JackNetAdapter.cpp
  9. +4
    -1
      common/JackNetDriver.cpp
  10. +348
    -281
      common/JackNetInterface.cpp
  11. +15
    -18
      common/JackNetInterface.h
  12. +7
    -6
      common/JackNetManager.cpp
  13. +499
    -69
      common/JackNetTool.cpp
  14. +453
    -20
      common/JackNetTool.h
  15. +29
    -0
      common/JackResampler.cpp
  16. +3
    -0
      common/JackResampler.h
  17. +1
    -1
      common/JackTools.h
  18. +1
    -0
      common/JackWaitThreadedDriver.h
  19. +321
    -0
      common/jack/net.h
  20. +10
    -9
      common/ringbuffer.c
  21. +32
    -0
      common/wscript
  22. +181
    -0
      example-clients/netmaster.c
  23. +168
    -0
      example-clients/netslave.c
  24. +8
    -1
      example-clients/wscript
  25. +18
    -2
      macosx/JackMachThread.cpp
  26. +11
    -0
      macosx/JackMachThread.h
  27. +22
    -6
      macosx/JackPlatformPlug_os.h
  28. +2
    -0
      macosx/Jackdmp.xcodeproj/project.pbxproj
  29. +1
    -1
      macosx/coreaudio/JackCoreAudioAdapter.h
  30. +409
    -0
      macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp
  31. +116
    -0
      macosx/coreaudio/TiPhoneCoreAudioRenderer.h
  32. +30
    -0
      macosx/iphone/Info.plist
  33. +440
    -0
      macosx/iphone/MainWindow.xib
  34. +754
    -0
      macosx/iphone/freeverb.mm
  35. +1291
    -0
      macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj
  36. +23
    -0
      macosx/iphone/iPhoneNetAppDelegate.h
  37. +32
    -0
      macosx/iphone/iPhoneNetAppDelegate.m
  38. +10
    -0
      macosx/iphone/iPhoneNet_Prefix.pch
  39. BIN
      macosx/iphone/icon.png
  40. +155
    -0
      macosx/iphone/main_master.mm
  41. +113
    -0
      macosx/iphone/main_slave.mm
  42. +1
    -0
      windows/jackd.workspace
  43. +149
    -0
      windows/libjacknet.cbp
  44. +41
    -0
      windows/libjacknet.rc

+ 28
- 29
ChangeLog View File

@@ -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

+ 66
- 43
common/JackAudioAdapterInterface.cpp View File

@@ -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

+ 26
- 8
common/JackAudioAdapterInterface.h View File

@@ -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);

};



+ 53
- 53
common/JackEngineProfiling.cpp View File

@@ -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

+ 63
- 53
common/JackFilters.h View File

@@ -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;
}
}
};

}


+ 3
- 3
common/JackGlobals.h View File

@@ -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);


+ 1005
- 0
common/JackNetAPI.cpp
File diff suppressed because it is too large
View File


+ 41
- 23
common/JackNetAdapter.cpp View File

@@ -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


+ 4
- 1
common/JackNetDriver.cpp View File

@@ -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;


+ 348
- 281
common/JackNetInterface.cpp
File diff suppressed because it is too large
View File


+ 15
- 18
common/JackNetInterface.h View File

@@ -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

+ 7
- 6
common/JackNetManager.cpp View File

@@ -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);


+ 499
- 69
common/JackNetTool.cpp View File

@@ -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 ( "**********************************************" );


+ 453
- 20
common/JackNetTool.h View File

@@ -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 *************************************************************************************



+ 29
- 0
common/JackResampler.cpp View File

@@ -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);


+ 3
- 0
common/JackResampler.h View File

@@ -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();



+ 1
- 1
common/JackTools.h View File

@@ -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 )


+ 1
- 0
common/JackWaitThreadedDriver.h View File

@@ -70,6 +70,7 @@ class SERVER_EXPORT JackWaitThreadedDriver : public JackThreadedDriver
} else {
jack_error("Initing net driver fails...");
}

return false;
}



+ 321
- 0
common/jack/net.h View File

@@ -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__ */

+ 10
- 9
common/ringbuffer.c View File

@@ -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


+ 32
- 0
common/wscript View File

@@ -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'


+ 181
- 0
example-clients/netmaster.c View File

@@ -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);
}

+ 168
- 0
example-clients/netslave.c View File

@@ -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);
}

+ 8
- 1
example-clients/wscript View File

@@ -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
- 2
macosx/JackMachThread.cpp View File

@@ -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 {


+ 11
- 0
macosx/JackMachThread.h View File

@@ -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


+ 22
- 6
macosx/JackPlatformPlug_os.h View File

@@ -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"


+ 2
- 0
macosx/Jackdmp.xcodeproj/project.pbxproj View File

@@ -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",


+ 1
- 1
macosx/coreaudio/JackCoreAudioAdapter.h View File

@@ -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()
{}



+ 409
- 0
macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp View File

@@ -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;
}
}

+ 116
- 0
macosx/coreaudio/TiPhoneCoreAudioRenderer.h View File

@@ -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

+ 30
- 0
macosx/iphone/Info.plist View File

@@ -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>

+ 440
- 0
macosx/iphone/MainWindow.xib View File

@@ -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>

+ 754
- 0
macosx/iphone/freeverb.mm View File

@@ -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;
}

+ 1291
- 0
macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj
File diff suppressed because it is too large
View File


+ 23
- 0
macosx/iphone/iPhoneNetAppDelegate.h View File

@@ -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


+ 32
- 0
macosx/iphone/iPhoneNetAppDelegate.m View File

@@ -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

+ 10
- 0
macosx/iphone/iPhoneNet_Prefix.pch View File

@@ -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

BIN
macosx/iphone/icon.png View File

Before After
Width: 48  |  Height: 48  |  Size: 5.2KB

+ 155
- 0
macosx/iphone/main_master.mm View File

@@ -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;
}

+ 113
- 0
macosx/iphone/main_slave.mm View File

@@ -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;
}

+ 1
- 0
windows/jackd.workspace View File

@@ -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" />


+ 149
- 0
windows/libjacknet.cbp View File

@@ -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>

+ 41
- 0
windows/libjacknet.rc View 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

Loading…
Cancel
Save