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