Browse Source

Add audio code for iPod, streaming from Mac to iPod (in master mode) now somewhat works.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3922 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.9.8
sletz 15 years ago
parent
commit
bae05a4f07
7 changed files with 556 additions and 447 deletions
  1. +0
    -314
      macosx/coreaudio/JackAudioQueueAdapter.cpp
  2. +0
    -99
      macosx/coreaudio/JackAudioQueueAdapter.h
  3. +390
    -0
      macosx/coreaudio/TiPhoneCoreAudioRenderer.cpp
  4. +103
    -0
      macosx/coreaudio/TiPhoneCoreAudioRenderer.h
  5. +16
    -2
      macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj
  6. +47
    -28
      macosx/iphone/main_master.mm
  7. +0
    -4
      macosx/iphone/main_slave.mm

+ 0
- 314
macosx/coreaudio/JackAudioQueueAdapter.cpp View File

@@ -1,314 +0,0 @@
/*
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 "JackAudioQueueAdapter.h"
//#include <CoreServices/CoreServices.h>

namespace Jack
{

// NOT YET WORKING....

static void Print4CharCode(const char* msg, long c)
{
UInt32 __4CC_number = (c);
char __4CC_string[5];
//*((SInt32*)__4CC_string) = EndianU32_NtoB(__4CC_number);
__4CC_string[4] = 0;
//printf("%s'%s'\n", (msg), __4CC_string);
snprintf(__4CC_string, 5, "%s'%s'\n", (msg), __4CC_string);
}
static int ComputeRecordBufferSize(AudioQueueRef mQueue, const AudioStreamBasicDescription *format, float seconds)
{
OSStatus err;
int packets, frames, bytes = 0;
frames = (int)ceil(seconds * format->mSampleRate);
if (format->mBytesPerFrame > 0)
bytes = frames * format->mBytesPerFrame;
else {
UInt32 maxPacketSize;
if (format->mBytesPerPacket > 0) {
maxPacketSize = format->mBytesPerPacket; // constant packet size
} else {
UInt32 propertySize = sizeof(maxPacketSize);
if ((err = AudioQueueGetProperty(mQueue, kAudioQueueProperty_MaximumOutputPacketSize, &maxPacketSize, &propertySize)) != noErr) {
printf("Couldn't get queue's maximum output packet size\n");
return 0;
}
}
if (format->mFramesPerPacket > 0)
packets = frames / format->mFramesPerPacket;
else
packets = frames; // worst-case scenario: 1 frame in a packet
if (packets == 0) // sanity check
packets = 1;
bytes = packets * maxPacketSize;
}
return bytes;
}

void JackAudioQueueAdapter::CaptureCallback(void * inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp * inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription *inPacketDesc)
{
JackAudioQueueAdapter* adapter = (JackAudioQueueAdapter*)inUserData;
OSStatus err;
printf("JackAudioQueueAdapter::CaptureCallback\n");
// Use the adapter to communicate with audio callback
// jack_adapter_push_input(adapter, audio_output, audio_output_buffer);
if ((err = AudioQueueEnqueueBuffer(adapter->fCaptureQueue, inBuffer, 0, NULL)) != noErr) {
printf("JackAudioQueueAdapter::CaptureCallback error %d\n", err);
} else {
printf("JackAudioQueueAdapter::CaptureCallback enqueue buffer\n");
}
}

void JackAudioQueueAdapter::PlaybackCallback(void * inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inCompleteAQBuffer)
{
JackAudioQueueAdapter* adapter = (JackAudioQueueAdapter*)inUserData;
OSStatus err;
printf("JackAudioQueueAdapter::PlaybackCallback\n");
// Use the adapter to communicate with audio callback
// jack_adapter_pull_output(adapter, audio_input, audio_input_buffer);
//if (AudioQueueEnqueueBuffer(adapter->fPlaybackQueue, inCompleteAQBuffer, 0, &adapter->fPlaybackPacketDescs) != noErr) {
if ((err = AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, 0, NULL)) != noErr) {
printf("JackAudioQueueAdapter::PlaybackCallback error %d\n", err);
} else {
printf("JackAudioQueueAdapter::PlaybackCallback enqueue buffer\n");
}
}

void JackAudioQueueAdapter::InterruptionListener(void* inClientData, UInt32 inInterruptionState)
{
JackAudioQueueAdapter* obj = (JackAudioQueueAdapter*)inClientData;
}

void JackAudioQueueAdapter::PropListener(void* inClientData,
AudioSessionPropertyID inID,
UInt32 inDataSize,
const void* inData)
{}


JackAudioQueueAdapter::JackAudioQueueAdapter(int inchan, int outchan, jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_adapter_t* adapter)
:fCaptureChannels(inchan), fPlaybackChannels(outchan), fBufferSize(buffer_size), fSampleRate(sample_rate), fAdapter(adapter)
{}

JackAudioQueueAdapter::~JackAudioQueueAdapter()
{}

int JackAudioQueueAdapter::Open()
{
OSStatus err;
int bufferByteSize;
UInt32 size;
/*
err = AudioSessionInitialize(NULL, NULL, InterruptionListener, this);
if (err != noErr) {
fprintf(stderr, "AudioSessionInitialize error %d\n", err);
return -1;
}
err = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, PropListener, this);
if (err) {
fprintf(stderr, "kAudioSessionProperty_AudioRouteChange error %d\n", err);
}
UInt32 inputAvailable = 0;
UInt32 size = sizeof(inputAvailable);
// we do not want to allow recording if input is not available
err = AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable, &size, &inputAvailable);
if (err != noErr) {
fprintf(stderr, "kAudioSessionProperty_AudioInputAvailable error %d\n", err);
}
// we also need to listen to see if input availability changes
err = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioInputAvailable, PropListener, this);
if (err != noErr) {
fprintf(stderr, "kAudioSessionProperty_AudioInputAvailable error %d\n", err);
}

err = AudioSessionSetActive(true);
if (err != noErr) {
fprintf(stderr, "AudioSessionSetActive (true) failed %d", err);
return -1;
}
*/
AudioStreamBasicDescription captureDataFormat;
/*
captureDataFormat.mSampleRate = fSampleRate;
captureDataFormat.mFormatID = kAudioFormatLinearPCM;
//captureDataFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
captureDataFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
captureDataFormat.mBytesPerPacket = sizeof(float);
captureDataFormat.mFramesPerPacket = 1;
captureDataFormat.mBytesPerFrame = sizeof(float);
captureDataFormat.mChannelsPerFrame = fCaptureChannels;
captureDataFormat.mBitsPerChannel = 32;
*/
captureDataFormat.mSampleRate = fSampleRate;
captureDataFormat.mFormatID = kAudioFormatLinearPCM;
captureDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
captureDataFormat.mBytesPerPacket = 4;
captureDataFormat.mFramesPerPacket = 1; // this means each packet in the AQ has two samples, one for each channel -> 4 bytes/frame/packet
captureDataFormat.mBytesPerFrame = 4;
captureDataFormat.mChannelsPerFrame = 2;
captureDataFormat.mBitsPerChannel = 16;

if ((err = AudioQueueNewInput(&captureDataFormat, CaptureCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &fCaptureQueue)) != noErr) {
Print4CharCode("error code : unknown", err);
return -1;
}
size = sizeof(captureDataFormat.mSampleRate);
if ((err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &size, &captureDataFormat.mSampleRate)) != noErr) {
printf("couldn't get hardware sample rate\n");
}
size = sizeof(captureDataFormat.mChannelsPerFrame);
if ((err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &size, &captureDataFormat.mChannelsPerFrame)) != noErr) {
printf("couldn't get input channel count\n");
}
size = sizeof(captureDataFormat);
if ((err = AudioQueueGetProperty(fCaptureQueue, kAudioQueueProperty_StreamDescription, &captureDataFormat, &size)) != noErr) {
printf("couldn't get queue's format\n");
}
bufferByteSize = ComputeRecordBufferSize(fCaptureQueue, &captureDataFormat, kBufferDurationSeconds); // enough bytes for half a second
for (int i = 0; i < kNumberBuffers; ++i) {
if ((err = AudioQueueAllocateBuffer(fCaptureQueue, bufferByteSize, &fCaptureQueueBuffers[i])) != noErr) {
printf("Capture AudioQueueAllocateBuffer failed\n");
}
if ((err = AudioQueueEnqueueBuffer(fCaptureQueue, fCaptureQueueBuffers[i], 0, NULL)) != noErr) {
printf("Capture AudioQueueEnqueueBuffer failed\n");
}
}
//AudioQueueSetProperty(fCaptureQueue, kAudioQueueProperty_MagicCookie, cookie, size)
//AudioQueueSetProperty(fCaptureQueue, kAudioQueueProperty_ChannelLayout, acl, size
AudioStreamBasicDescription playbackDataFormat;
/*
playbackDataFormat.mSampleRate = fSampleRate;
playbackDataFormat.mFormatID = kAudioFormatLinearPCM;
playbackDataFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
playbackDataFormat.mBytesPerPacket = sizeof(float);
playbackDataFormat.mFramesPerPacket = 1;
playbackDataFormat.mBytesPerFrame = sizeof(float);
playbackDataFormat.mChannelsPerFrame = fPlaybackChannels;
playbackDataFormat.mBitsPerChannel = 32;
*/
playbackDataFormat.mSampleRate = fSampleRate;
playbackDataFormat.mFormatID = kAudioFormatLinearPCM;
playbackDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
playbackDataFormat.mBytesPerPacket = 4;
playbackDataFormat.mFramesPerPacket = 1;
playbackDataFormat.mBytesPerFrame = 4;
playbackDataFormat.mChannelsPerFrame = fPlaybackChannels;
playbackDataFormat.mBitsPerChannel = 16;
if ((err = AudioQueueNewOutput(&playbackDataFormat, PlaybackCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &fPlaybackQueue)) != noErr) {
Print4CharCode("error code : unknown", err);
return -1;
}
for (int i = 0; i < kNumberBuffers; ++i) {
if ((err = AudioQueueAllocateBuffer(fPlaybackQueue, bufferByteSize, &fPlaybackQueueBuffers[i])) != noErr) {
printf("Playback AudioQueueAllocateBuffer failed %d\n", err);
}
//if ((err = AudioQueueEnqueueBuffer(fPlaybackQueue, fPlaybackQueueBuffers[i], 0, NULL)) != noErr) {
// printf("Playback AudioQueueEnqueueBuffer failed %d\n", err);
//}
}
AudioQueueSetParameter(fPlaybackQueue, kAudioQueueParam_Volume, 1.0);
//AudioQueueSetProperty(fPlaybackQueue, kAudioQueueProperty_MagicCookie, cookie, size);
//AudioQueueSetProperty(fPlaybackQueue, kAudioQueueProperty_ChannelLayout, acl, size);
//AudioQueueSetParameter(fPlaybackQueue, kAudioQueueParam_Volume, volume
return 0;
}
int JackAudioQueueAdapter::Close()
{
//AudioSessionSetActive(false);
AudioQueueDispose(fCaptureQueue, true);
AudioQueueDispose(fPlaybackQueue, true);
return 0;
}
int JackAudioQueueAdapter::Start()
{
for (int i = 0; i < kNumberBuffers; ++i) {
PlaybackCallback(this, fPlaybackQueue, fPlaybackQueueBuffers[i]);
}

AudioQueueStart(fCaptureQueue, NULL);
AudioQueueStart(fPlaybackQueue, NULL);
return 0;
}
int JackAudioQueueAdapter::Stop()
{
AudioQueueStop(fCaptureQueue, NULL);
AudioQueueStop(fPlaybackQueue, NULL);
return 0;
}


int JackAudioQueueAdapter::SetSampleRate(jack_nframes_t sample_rate)
{
return 0;
}

int JackAudioQueueAdapter::SetBufferSize(jack_nframes_t buffer_size)
{
return 0;
}
};

+ 0
- 99
macosx/coreaudio/JackAudioQueueAdapter.h View File

@@ -1,99 +0,0 @@
/*
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.

*/

#ifndef __JackAudioQueueAdapter__
#define __JackAudioQueueAdapter__

//#include <AudioToolbox/AudioConverter.h>
//#include <AudioToolbox/AudioQueue.h>

#include <AudioToolbox/AudioToolbox.h>

#include <jack/net.h>

namespace Jack
{

/*!
\brief Audio adapter using AudioQueue API.
*/

#define kNumberBuffers 3
#define kBufferDurationSeconds .5

class JackAudioQueueAdapter
{

private:

AudioQueueRef fCaptureQueue;
AudioQueueBufferRef fCaptureQueueBuffers[kNumberBuffers];
AudioQueueRef fPlaybackQueue;
AudioQueueBufferRef fPlaybackQueueBuffers[kNumberBuffers];
//AudioStreamPacketDescription fPlaybackPacketDescs;
jack_nframes_t fBufferSize;
jack_nframes_t fSampleRate;

int fCaptureChannels;
int fPlaybackChannels;
jack_adapter_t* fAdapter;
static void CaptureCallback(void* inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp* inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription* inPacketDesc);


static void PlaybackCallback(void* inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inCompleteAQBuffer);
static void InterruptionListener(void* inClientData, UInt32 inInterruptionState);
static void PropListener(void* inClientData,
AudioSessionPropertyID inID,
UInt32 inDataSize,
const void* inData);

public:

JackAudioQueueAdapter(int inchan, int outchan, jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_adapter_t* adapter);
~JackAudioQueueAdapter();
virtual int Open();
virtual int Close();
virtual int Start();
virtual int Stop();

virtual int SetSampleRate(jack_nframes_t sample_rate);
virtual int SetBufferSize(jack_nframes_t buffer_size);

};

}

#endif

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

@@ -0,0 +1,390 @@
/*
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, ioData);
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->PerformAudioCallback((int)inNumberFrames);
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);
}
}
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::OpenDefault(int bufferSize, int samplerate)
{
OSStatus err1;
UInt32 outSize;
UInt32 enableIO;
AudioStreamBasicDescription srcFormat, dstFormat;
printf("OpenDefault 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;
}
}

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

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

@@ -0,0 +1,103 @@
/*
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;
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)
:fDevNumInChans(input), fDevNumOutChans(output), fAudioCallback(NULL), fCallbackArg(NULL)
{
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];
}
}

int OpenDefault(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

+ 16
- 2
macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj View File

@@ -19,7 +19,6 @@
4B0772280F54018C000DC657 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; 4B0772280F54018C000DC657 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; };
4B0772290F54018C000DC657 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; 4B0772290F54018C000DC657 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; };
4B07722A0F54018C000DC657 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; 4B07722A0F54018C000DC657 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; };
4B07722B0F54018C000DC657 /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; };
4B07722C0F54018C000DC657 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4B07722C0F54018C000DC657 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; };
4B07722D0F54018C000DC657 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; 4B07722D0F54018C000DC657 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; };
4B07722E0F54018C000DC657 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; 4B07722E0F54018C000DC657 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; };
@@ -116,6 +115,12 @@
4BF15E2811356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4BF15E2811356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; };
4BF15E2911356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4BF15E2911356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; };
4BF15E2A11356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; }; 4BF15E2A11356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */; };
4BF15F7811357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; };
4BF15F7911357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; };
4BF15F7A11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; };
4BF15F7B11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; };
4BF15F7C11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; };
4BF15F7D11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */; };
4BFF45600F4D5D9700106083 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 4BFF45600F4D5D9700106083 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; };
4BFF45630F4D5D9700106083 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; 4BFF45630F4D5D9700106083 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; };
4BFF45640F4D5D9700106083 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; 4BFF45640F4D5D9700106083 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; };
@@ -173,6 +178,7 @@
4BF1364C0F4B0F7700218A3F /* JackResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackResampler.h; path = ../../common/JackResampler.h; sourceTree = SOURCE_ROOT; }; 4BF1364C0F4B0F7700218A3F /* JackResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackResampler.h; path = ../../common/JackResampler.h; sourceTree = SOURCE_ROOT; };
4BF136540F4B0F9F00218A3F /* ringbuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ringbuffer.c; path = ../../common/ringbuffer.c; sourceTree = SOURCE_ROOT; }; 4BF136540F4B0F9F00218A3F /* ringbuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ringbuffer.c; path = ../../common/ringbuffer.c; sourceTree = SOURCE_ROOT; };
4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CAHostTimeBase.cpp; path = /Developer/Extras/CoreAudio/PublicUtility/CAHostTimeBase.cpp; sourceTree = "<absolute>"; }; 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CAHostTimeBase.cpp; path = /Developer/Extras/CoreAudio/PublicUtility/CAHostTimeBase.cpp; sourceTree = "<absolute>"; };
4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TiPhoneCoreAudioRenderer.cpp; path = ../coreaudio/TiPhoneCoreAudioRenderer.cpp; sourceTree = SOURCE_ROOT; };
4BFF45120F4D59DB00106083 /* libjacknet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjacknet.a; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFF45120F4D59DB00106083 /* libjacknet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjacknet.a; sourceTree = BUILT_PRODUCTS_DIR; };
4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -275,6 +281,7 @@
4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */, 4BCB37D8112D64D8008C7BC1 /* iphone-faust.mm */,
4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */, 4BCB37D5112D64B4008C7BC1 /* HardwareClock.cpp */,
4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */, 4BF15E2411356A3E00B36B9A /* CAHostTimeBase.cpp */,
4BF15F7711357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp */,
29B97315FDCFA39411CA2CEA /* Other Sources */, 29B97315FDCFA39411CA2CEA /* Other Sources */,
29B97317FDCFA39411CA2CEA /* Resources */, 29B97317FDCFA39411CA2CEA /* Resources */,
29B97323FDCFA39411CA2CEA /* Frameworks */, 29B97323FDCFA39411CA2CEA /* Frameworks */,
@@ -567,6 +574,7 @@
4B0773870F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, 4B0773870F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */,
4B27918A0F72570C000536B7 /* JackGlobals.cpp in Sources */, 4B27918A0F72570C000536B7 /* JackGlobals.cpp in Sources */,
4BF15E2611356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15E2611356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */,
4BF15F7911357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -581,7 +589,6 @@
4B0772280F54018C000DC657 /* JackNetTool.cpp in Sources */, 4B0772280F54018C000DC657 /* JackNetTool.cpp in Sources */,
4B0772290F54018C000DC657 /* JackNetUnixSocket.cpp in Sources */, 4B0772290F54018C000DC657 /* JackNetUnixSocket.cpp in Sources */,
4B07722A0F54018C000DC657 /* JackPosixThread.cpp in Sources */, 4B07722A0F54018C000DC657 /* JackPosixThread.cpp in Sources */,
4B07722B0F54018C000DC657 /* JackAudioQueueAdapter.cpp in Sources */,
4B07722C0F54018C000DC657 /* JackAudioAdapterInterface.cpp in Sources */, 4B07722C0F54018C000DC657 /* JackAudioAdapterInterface.cpp in Sources */,
4B07722D0F54018C000DC657 /* JackResampler.cpp in Sources */, 4B07722D0F54018C000DC657 /* JackResampler.cpp in Sources */,
4B07722E0F54018C000DC657 /* ringbuffer.c in Sources */, 4B07722E0F54018C000DC657 /* ringbuffer.c in Sources */,
@@ -589,6 +596,7 @@
4B0773860F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, 4B0773860F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */,
4B27918B0F72570C000536B7 /* JackGlobals.cpp in Sources */, 4B27918B0F72570C000536B7 /* JackGlobals.cpp in Sources */,
4BF15E2511356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15E2511356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */,
4BF15F7811357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -629,6 +637,7 @@
4B4146A610BD3C4300C12F0C /* freeverb.mm in Sources */, 4B4146A610BD3C4300C12F0C /* freeverb.mm in Sources */,
4B4146A710BD3C4300C12F0C /* JackGlobals.cpp in Sources */, 4B4146A710BD3C4300C12F0C /* JackGlobals.cpp in Sources */,
4BF15E2911356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15E2911356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */,
4BF15F7C11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -639,6 +648,7 @@
4BCB37D6112D64B4008C7BC1 /* HardwareClock.cpp in Sources */, 4BCB37D6112D64B4008C7BC1 /* HardwareClock.cpp in Sources */,
4BCB37D9112D64D8008C7BC1 /* iphone-faust.mm in Sources */, 4BCB37D9112D64D8008C7BC1 /* iphone-faust.mm in Sources */,
4BF15E2A11356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15E2A11356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */,
4BF15F7D11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -661,6 +671,7 @@
4BCF75E910BC2FD90082C526 /* JackGlobals.cpp in Sources */, 4BCF75E910BC2FD90082C526 /* JackGlobals.cpp in Sources */,
4BCF75F710BC30140082C526 /* audio_thru.mm in Sources */, 4BCF75F710BC30140082C526 /* audio_thru.mm in Sources */,
4BF15E2811356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15E2811356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */,
4BF15F7B11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -683,6 +694,7 @@
4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */, 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */,
4B2791880F72570C000536B7 /* JackGlobals.cpp in Sources */, 4B2791880F72570C000536B7 /* JackGlobals.cpp in Sources */,
4BF15E2711356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */, 4BF15E2711356A3E00B36B9A /* CAHostTimeBase.cpp in Sources */,
4BF15F7A11357A0E00B36B9A /* TiPhoneCoreAudioRenderer.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -747,6 +759,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
../../macosx/coreaudio,
../../macosx, ../../macosx,
../../posix, ../../posix,
../../common/jack, ../../common/jack,
@@ -771,6 +784,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
../../macosx/coreaudio,
../../common/jack, ../../common/jack,
../../common, ../../common,
../../posix, ../../posix,


+ 47
- 28
macosx/iphone/main_master.mm View File

@@ -9,7 +9,7 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#include <jack/net.h> #include <jack/net.h>


#include "JackAudioQueueAdapter.h"
#include "TiPhoneCoreAudioRenderer.h"


#define NUM_INPUT 2 #define NUM_INPUT 2
#define NUM_OUTPUT 2 #define NUM_OUTPUT 2
@@ -17,27 +17,34 @@
jack_net_master_t* net; jack_net_master_t* net;
jack_adapter_t* adapter; jack_adapter_t* adapter;


Jack::JackAudioQueueAdapter* audio;
float** audio_input_buffer;
float** audio_output_buffer;


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 buffer_size = 2048;
int sample_rate = 44100;

jack_master_t request = { buffer_size, sample_rate, "master" };
jack_slave_t result;

void MasterAudioCallback(int frames, float** inputs, float** outputs, void* arg)
{ {
// Process input, produce output
if (audio_input == audio_output) {
// Copy input to output
for (int i = 0; i < audio_input; i++) {
memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float));
}
int i;
for (i = 0; i < result.audio_input; i++) {
memcpy(audio_output_buffer[i], inputs[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");
}
for (i = 0; i < result.audio_output; i++) {
memcpy(outputs[i], audio_input_buffer[i], buffer_size * sizeof(float));
} }
return 0;
} }


int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@@ -45,14 +52,9 @@ int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int i; int i;
int buffer_size = 2048;
int sample_rate = 44100;
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));

TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT);
if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) {
return -1; return -1;
} }
@@ -68,8 +70,24 @@ int main(int argc, char *argv[]) {
audio_output_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); audio_output_buffer[i] = (float*)(calloc(buffer_size, sizeof(float)));
} }
// Quite brutal way, the application actually does not start completely, the netjack audio processing loop is used instead...
if (audio_device.OpenDefault(buffer_size, sample_rate) < 0) {
return -1;
}
audio_device.SetAudioCallback(MasterAudioCallback, NULL);
if (audio_device.Start() < 0) {
return -1;
}
// Run until interrupted
while (1) {}
audio_device.Stop();
audio_device.Close();


/*
// Quite brutal way, the application actually does not start completely, the netjack audio processing loop is used instead...
// Run until interrupted // Run until interrupted
while (1) { while (1) {
@@ -89,6 +107,7 @@ int main(int argc, char *argv[]) {
} }
usleep(wait_usec); usleep(wait_usec);
}; };
*/
// Wait for application end // Wait for application end
jack_net_master_close(net); jack_net_master_close(net);


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

@@ -9,16 +9,12 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#include <jack/net.h> #include <jack/net.h>


#include "JackAudioQueueAdapter.h"

#define NUM_INPUT 2 #define NUM_INPUT 2
#define NUM_OUTPUT 2 #define NUM_OUTPUT 2


jack_net_slave_t* net; jack_net_slave_t* net;
jack_adapter_t* adapter; jack_adapter_t* adapter;


Jack::JackAudioQueueAdapter* audio;

static int net_process(jack_nframes_t buffer_size, static int net_process(jack_nframes_t buffer_size,
int audio_input, int audio_input,
float** audio_input_buffer, float** audio_input_buffer,


Loading…
Cancel
Save