git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3956 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.8
@@ -145,6 +145,10 @@ struct JackNetExtMaster : public JackNetMasterInterface { | |||
fSocket.SetPort(port); | |||
fRequest.buffer_size = request->buffer_size; | |||
fRequest.sample_rate = request->sample_rate; | |||
fAudioCaptureBuffer = NULL; | |||
fAudioPlaybackBuffer = NULL; | |||
fMidiCaptureBuffer = NULL; | |||
fMidiPlaybackBuffer = NULL; | |||
} | |||
virtual ~JackNetExtMaster() | |||
@@ -283,28 +287,36 @@ struct JackNetExtMaster : public JackNetMasterInterface { | |||
unsigned int port_index; | |||
// Set buffers | |||
fAudioPlaybackBuffer = new float*[fParams.fSendAudioChannels]; | |||
for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) { | |||
fAudioPlaybackBuffer[port_index] = new float[fParams.fPeriodSize]; | |||
fNetAudioPlaybackBuffer->SetBuffer(port_index, fAudioPlaybackBuffer[port_index]); | |||
if (fParams.fSendAudioChannels > 0) { | |||
fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels]; | |||
for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) { | |||
fAudioCaptureBuffer[port_index] = new float[fParams.fPeriodSize]; | |||
fNetAudioCaptureBuffer->SetBuffer(port_index, fAudioCaptureBuffer[port_index]); | |||
} | |||
} | |||
fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels]; | |||
for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) { | |||
fMidiPlaybackBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; | |||
fNetMidiPlaybackBuffer->SetBuffer(port_index, fMidiPlaybackBuffer[port_index]); | |||
if (fParams.fSendMidiChannels > 0) { | |||
fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels]; | |||
for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) { | |||
fMidiCaptureBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; | |||
fNetMidiCaptureBuffer->SetBuffer(port_index, fMidiCaptureBuffer[port_index]); | |||
} | |||
} | |||
fAudioCaptureBuffer = new float*[fParams.fReturnAudioChannels]; | |||
for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) { | |||
fAudioCaptureBuffer[port_index] = new float[fParams.fPeriodSize]; | |||
fNetAudioCaptureBuffer->SetBuffer(port_index, fAudioCaptureBuffer[port_index]); | |||
} | |||
if (fParams.fReturnAudioChannels > 0) { | |||
fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels]; | |||
for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) { | |||
fAudioPlaybackBuffer[port_index] = new float[fParams.fPeriodSize]; | |||
fNetAudioPlaybackBuffer->SetBuffer(port_index, fAudioPlaybackBuffer[port_index]); | |||
} | |||
} | |||
fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels]; | |||
for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) { | |||
fMidiCaptureBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; | |||
fNetMidiCaptureBuffer->SetBuffer(port_index, fMidiCaptureBuffer[port_index]); | |||
if (fParams.fReturnMidiChannels > 0) { | |||
fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels]; | |||
for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) { | |||
fMidiPlaybackBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; | |||
fNetMidiPlaybackBuffer->SetBuffer(port_index, fMidiPlaybackBuffer[port_index]); | |||
} | |||
} | |||
} | |||
@@ -344,14 +356,13 @@ struct JackNetExtMaster : public JackNetMasterInterface { | |||
int Read(int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer) | |||
{ | |||
try { | |||
assert((unsigned int)audio_input == fParams.fSendAudioChannels); | |||
int port_index; | |||
assert((unsigned int)audio_input == fParams.fReturnAudioChannels); | |||
for (port_index = 0; port_index < audio_input; port_index++) { | |||
for (int port_index = 0; port_index < audio_input; port_index++) { | |||
fNetAudioPlaybackBuffer->SetBuffer(port_index, audio_input_buffer[port_index]); | |||
} | |||
for (port_index = 0; port_index < midi_input; port_index++) { | |||
for (int port_index = 0; port_index < midi_input; port_index++) { | |||
fNetMidiPlaybackBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_input_buffer)[port_index]); | |||
} | |||
@@ -370,14 +381,13 @@ struct JackNetExtMaster : public JackNetMasterInterface { | |||
int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer) | |||
{ | |||
try { | |||
assert((unsigned int)audio_output == fParams.fReturnAudioChannels); | |||
int port_index; | |||
assert((unsigned int)audio_output == fParams.fSendAudioChannels); | |||
for (port_index = 0; port_index < audio_output; port_index++) { | |||
for (int port_index = 0; port_index < audio_output; port_index++) { | |||
fNetAudioCaptureBuffer->SetBuffer(port_index, audio_output_buffer[port_index]); | |||
} | |||
for (port_index = 0; port_index < midi_output; port_index++) { | |||
for (int port_index = 0; port_index < midi_output; port_index++) { | |||
fNetMidiCaptureBuffer->SetBuffer(port_index, ((JackMidiBuffer**)midi_output_buffer)[port_index]); | |||
} | |||
@@ -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 ); | |||
@@ -215,17 +221,22 @@ namespace Jack | |||
} | |||
//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 | |||
@@ -1983,7 +1983,7 @@ extern "C" | |||
bool capture = false; | |||
bool playback = false; | |||
int chan_in = -1; // Default: if not explicitely set, then max possible will be used... | |||
int chan_out = -1; // Default: ifĂ not explicitely set, then max possible will be used... | |||
int chan_out = -1; // Default: if not explicitely set, then max possible will be used... | |||
bool monitor = false; | |||
const char* capture_driver_uid = ""; | |||
const char* playback_driver_uid = ""; | |||
@@ -80,14 +80,14 @@ OSStatus TiPhoneCoreAudioRenderer::Render(void *inRefCon, | |||
AudioBufferList *ioData) | |||
{ | |||
TiPhoneCoreAudioRendererPtr renderer = (TiPhoneCoreAudioRendererPtr)inRefCon; | |||
AudioUnitRender(renderer->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, ioData); | |||
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(((long*)ioData->mBuffers[chan].mData)[frame]) * inv_coef; | |||
renderer->fInChannel[chan][frame] = float(((int*)renderer->fCAInputData->mBuffers[chan].mData)[frame]) * inv_coef; | |||
} | |||
} | |||
@@ -95,7 +95,7 @@ OSStatus TiPhoneCoreAudioRenderer::Render(void *inRefCon, | |||
for (int chan = 0; chan < renderer->fDevNumOutChans; chan++) { | |||
for (int frame = 0; frame < inNumberFrames; frame++) { | |||
((long*)ioData->mBuffers[chan].mData)[frame] = long(renderer->fOutChannel[chan][frame] * coef); | |||
((int*)ioData->mBuffers[chan].mData)[frame] = int(renderer->fOutChannel[chan][frame] * coef); | |||
} | |||
} | |||
@@ -326,7 +326,7 @@ int TiPhoneCoreAudioRenderer::Open(int bufferSize, int samplerate) | |||
printError(err1); | |||
} | |||
} | |||
if (fDevNumInChans > 0 && fDevNumOutChans == 0) { | |||
AURenderCallbackStruct output; | |||
output.inputProc = Render; | |||
@@ -348,6 +348,25 @@ int TiPhoneCoreAudioRenderer::Open(int bufferSize, int samplerate) | |||
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; | |||
@@ -41,6 +41,8 @@ class TiPhoneCoreAudioRenderer | |||
int fDevNumInChans; | |||
int fDevNumOutChans; | |||
AudioBufferList* fCAInputData; | |||
float* fInChannel[MAX_CHANNELS]; | |||
float* fOutChannel[MAX_CHANNELS]; | |||
@@ -57,7 +59,7 @@ class TiPhoneCoreAudioRenderer | |||
public: | |||
TiPhoneCoreAudioRenderer(int input, int output) | |||
:fDevNumInChans(input), fDevNumOutChans(output), fAudioCallback(NULL), fCallbackArg(NULL) | |||
:fAudioCallback(NULL), fCallbackArg(NULL), fDevNumInChans(input), fDevNumOutChans(output), fCAInputData(NULL) | |||
{ | |||
memset(fInChannel, 0, sizeof(float*) * MAX_CHANNELS); | |||
memset(fOutChannel, 0, sizeof(float*) * MAX_CHANNELS); | |||
@@ -70,6 +72,7 @@ class TiPhoneCoreAudioRenderer | |||
fOutChannel[i] = new float[8192]; | |||
} | |||
} | |||
virtual ~TiPhoneCoreAudioRenderer() | |||
{ | |||
for (int i = 0; i < fDevNumInChans; i++) { | |||
@@ -79,6 +82,13 @@ class TiPhoneCoreAudioRenderer | |||
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); | |||
@@ -184,9 +184,7 @@ | |||
4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "iphone-faust.mm"; sourceTree = SOURCE_ROOT; }; | |||
4BCF75F210BC2FD90082C526 /* iPhoneThruNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneThruNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; | |||
4BDFCCD7113DB30500D77992 /* Info copy.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info copy.plist"; sourceTree = "<group>"; }; | |||
4BDFCD57113DB6B700D77992 /* NetJackSlave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetJackSlave.app; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BDFCD59113DB6B700D77992 /* Info copy 2.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info copy 2.plist"; sourceTree = "<group>"; }; | |||
4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; | |||
4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapterInterface.h; path = ../../common/JackAudioAdapterInterface.h; sourceTree = SOURCE_ROOT; }; | |||
4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; }; | |||
@@ -354,8 +352,6 @@ | |||
28AD733E0D9D9553002E5188 /* MainWindow.xib */, | |||
8D1107310486CEB800E47090 /* Info.plist */, | |||
4BC9C1D31135AA1800D22670 /* iPhoneNetMasterAppl-Info.plist */, | |||
4BDFCCD7113DB30500D77992 /* Info copy.plist */, | |||
4BDFCD59113DB6B700D77992 /* Info copy 2.plist */, | |||
); | |||
name = Resources; | |||
sourceTree = "<group>"; | |||
@@ -17,37 +17,59 @@ | |||
jack_net_master_t* net; | |||
jack_adapter_t* adapter; | |||
float** audio_input_buffer; | |||
float** audio_output_buffer; | |||
float** audio_input_buffer = NULL; | |||
float** audio_output_buffer = NULL; | |||
int buffer_size = 1024; | |||
int sample_rate = 44100; | |||
int buffer_size = 512; | |||
int sample_rate = 32000; | |||
//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_output_buffer[i], inputs[i], buffer_size * sizeof(float)); | |||
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_output, audio_output_buffer, 0, NULL) < 0) { | |||
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_input, audio_input_buffer, 0, NULL) < 0) { | |||
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_input_buffer[i], buffer_size * sizeof(float)); | |||
memcpy(outputs[i], audio_output_buffer[i], buffer_size * sizeof(float)); | |||
} | |||
} | |||
@@ -58,22 +80,26 @@ int main(int argc, char *argv[]) { | |||
int i; | |||
int wait_usec = (unsigned long)((((float)buffer_size) / ((float)sample_rate)) * 1000000.0f); | |||
TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); | |||
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 | |||
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_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))); | |||
} | |||
} | |||
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 (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) { | |||
@@ -70,7 +70,7 @@ int main(int argc, char *argv[]) { | |||
//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"); | |||
printf("jack_net_master_open error..\n"); | |||
return -1; | |||
} | |||