text:
//-----------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/interappaudio/PresetManager.mm
// Created by  : Steinberg, 10/2013
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#import "PresetManager.h"
#import "public.sdk/source/vst/vstpresetfile.h"
#import "pluginterfaces/vst/ivstattributes.h"
#import "PresetBrowserViewController.h"
#import "PresetSaveViewController.h"

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

//-----------------------------------------------------------------------------
class PresetStream : public ReadOnlyBStream, public IStreamAttributes
{
public:
	PresetStream (IBStream* sourceStream, TSize sourceOffset, TSize sectionSize, const char* utf8Path)
	: ReadOnlyBStream (sourceStream, sourceOffset, sectionSize)
	, fileName (utf8Path)
	{
		fileName.toWideString (kCP_Utf8);
	}

	virtual tresult PLUGIN_API getFileName (String128 name)
	{
		if (fileName.length () > 0)
		{
			fileName.copyTo (name, 0, 128);
			return kResultTrue;
		}
		return kResultFalse;
	}
	virtual IAttributeList* PLUGIN_API getAttributes () { return 0; }

	DEF_INTERFACES_1(IStreamAttributes, ReadOnlyBStream)
	REFCOUNT_METHODS(ReadOnlyBStream)
protected:
	String fileName;
};

//-----------------------------------------------------------------------------
PresetManager::PresetManager (VST3Plugin* plugin, const TUID& cid)
: plugin (plugin)
, visiblePresetBrowserViewController (nil)
, visibleSavePresetViewController (nil)
, cid (cid)
{
	id obj = [[NSUserDefaults standardUserDefaults] objectForKey:@"PresetManager|lastPreset"];
	if (obj && [obj isKindOfClass:[NSString class]])
	{
		lastPreset = [obj UTF8String];
	}
}

//-----------------------------------------------------------------------------
NSArray* PresetManager::getPresetPaths (PresetPathType type)
{
	if (type == kFactory)
	{
		return [[NSBundle mainBundle] URLsForResourcesWithExtension:@"vstpreset" subdirectory:@"Presets"];
	}
	NSFileManager* fs = [NSFileManager defaultManager];
	NSURL* documentsUrl = [fs URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:Nil create:YES error:NULL];
	if (documentsUrl)
	{
		NSMutableArray* userUrls = [NSMutableArray new];
		NSDirectoryEnumerator* enumerator = [fs enumeratorAtURL:documentsUrl includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsSubdirectoryDescendants errorHandler:nil];
		for (NSURL* url in enumerator.allObjects)
		{
			if ([[url pathExtension] isEqualToString:@"vstpreset"])
			{
				[userUrls addObject:url];
			}
		}
		return [userUrls sortedArrayUsingComparator:^NSComparisonResult (NSURL* obj1, NSURL* obj2) {
					return [[obj1 lastPathComponent] caseInsensitiveCompare:[obj2 lastPathComponent]];
				}];
	}
	return nil;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API PresetManager::runLoadPresetBrowser ()
{
	if (visiblePresetBrowserViewController != nil)
		return kResultFalse;

	addRef ();
	visiblePresetBrowserViewController = [[PresetBrowserViewController alloc] initWithCallback:[this](const char* path) {
											  loadPreset (path);
											  visiblePresetBrowserViewController = nil;
											  release ();
										  }];
	addRef ();
	dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
		if (visiblePresetBrowserViewController)
		{
			[visiblePresetBrowserViewController setFactoryPresets:getPresetPaths (kFactory) userPresets:getPresetPaths (kUser)];
		}
		release ();
	});
	return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API PresetManager::runSavePresetBrowser ()
{
	if (visibleSavePresetViewController != nil)
		return kResultFalse;

	addRef ();
	visibleSavePresetViewController = [[PresetSaveViewController alloc] initWithCallback:[this](const char* path) {
										   savePreset (path);
										   visibleSavePresetViewController = nil;
										   release ();
									   }];
	return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API PresetManager::loadNextPreset ()
{
	return loadPreset (true);
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API PresetManager::loadPreviousPreset ()
{
	return loadPreset (false);
}

//-----------------------------------------------------------------------------
tresult PresetManager::loadPreset (bool next)
{
	NSArray* presets = [[getPresetPaths (kFactory) arrayByAddingObjectsFromArray:getPresetPaths (kUser)] sortedArrayUsingComparator:^NSComparisonResult (NSURL* obj1, NSURL* obj2) {
		return [[obj1 lastPathComponent] caseInsensitiveCompare:[obj2 lastPathComponent]];
	}];

	__block NSUInteger index = NSNotFound;
	if (lastPreset.isEmpty() == false)
	{
		NSURL* lastUrl = [[NSURL fileURLWithPath:[NSString stringWithUTF8String:lastPreset]] fileReferenceURL];
		if (lastUrl)
		{
			[presets enumerateObjectsUsingBlock:^(NSURL* obj, NSUInteger idx, BOOL *stop) {
				if ([[obj fileReferenceURL] isEqual:lastUrl])
				{
					index = idx;
					*stop = YES;
				}
			}];
		}
	}
	if (index == NSNotFound)
	{
		if (next)
			index = [presets count] - 1;
		else
			index = 1;
	}
	if (index != NSNotFound)
	{
		if (next)
		{
			if (index >= [presets count] - 1)
				index = 0;
			else
				index++;
		}
		else
		{
			if (index == 0)
				index = [presets count] - 1;
			else
				index--;
		}
		return loadPreset ([[[presets objectAtIndex:index] path] UTF8String]);
	}
	return kResultFalse;
}

//-----------------------------------------------------------------------------
tresult PresetManager::loadPreset (const char* path)
{
	if (path)
	{
		IPtr<IBStream> stream = owned (FileStream::open (path, "r"));
		if (stream)
		{
			[[NSUserDefaults standardUserDefaults] setObject:[NSString stringWithUTF8String:path] forKey:@"PresetManager|lastPreset"];
			lastPreset = path;
			FUnknownPtr<IComponent> component (plugin->getAudioProcessor ());
			IEditController* controller = plugin->getEditController ();
			if (component)
			{
				PresetFile pf (stream);
				if (!pf.readChunkList ())
					return kResultFalse;
				if (pf.getClassID () != cid)
					return kResultFalse;
				const PresetFile::Entry* e = pf.getEntry (kComponentState);
				if (e == 0)
					return kResultFalse;
				char* filename = strrchr (path, '/');
				if (filename)
					filename++;
				IPtr<PresetStream> readOnlyBStream = owned (new PresetStream (stream, e->offset, e->size, filename));
				tresult result = component->setState (readOnlyBStream);
				if ((result == kResultTrue || result == kNotImplemented) && controller)
				{
					readOnlyBStream->seek (0, IBStream::kIBSeekSet);
					controller->setComponentState (readOnlyBStream);
					if (pf.contains (kControllerState))
					{
						e = pf.getEntry (kControllerState);
						if (e)
						{
							readOnlyBStream = owned (new PresetStream (stream, e->offset, e->size, filename));
							controller->setState (readOnlyBStream);
						}
					}
				}
				return result;
			}
		}
	}
	return kResultFalse;
}

//-----------------------------------------------------------------------------
void PresetManager::savePreset (const char* path)
{
	IBStream* stream = FileStream::open (path, "w");
	if (stream)
	{
		FUnknownPtr<IComponent> component (plugin->getAudioProcessor ());
		IEditController* controller = plugin->getEditController ();
		if (component)
		{
			PresetFile::savePreset (stream, cid, component, controller);
		}
		stream->release ();
		loadPreset (path);
	}
}

}}} // namespaces


text:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="10117" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PresetBrowserViewController">
            <connections>
                <outlet property="containerView" destination="klJ-ou-M84" id="oc3-yW-Wj1"/>
                <outlet property="presetTableView" destination="7ve-UC-DYv" id="DY3-Yy-Nem"/>
                <outlet property="view" destination="2" id="3"/>
            </connections>
        </placeholder>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <view opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="2">
            <rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
            <subviews>
                <button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="RKH-M0-6se">
                    <rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
                    <color key="backgroundColor" white="1" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
                    <fontDescription key="fontDescription" type="system" pointSize="15"/>
                    <state key="normal" title="Button">
                        <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
                    </state>
                    <connections>
                        <action selector="cancel:" destination="-1" eventType="touchUpInside" id="HBx-cS-lfH"/>
                    </connections>
                </button>
                <view opaque="NO" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="klJ-ou-M84">
                    <rect key="frame" x="163" y="30" width="698" height="708"/>
                    <subviews>
                        <tableView opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="7ve-UC-DYv">
                            <rect key="frame" x="20" y="20" width="658" height="630"/>
                            <color key="backgroundColor" white="1" alpha="0.0" colorSpace="calibratedWhite"/>
                            <color key="separatorColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
                            <connections>
                                <outlet property="dataSource" destination="-1" id="FIu-tQ-zaK"/>
                                <outlet property="delegate" destination="-1" id="Wmb-vA-YdQ"/>
                            </connections>
                        </tableView>
                        <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IWt-40-Jgp">
                            <rect key="frame" x="20" y="668" width="48" height="30"/>
                            <state key="normal" title="Edit">
                                <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
                            </state>
                            <connections>
                                <action selector="toggleEditMode:" destination="-1" eventType="touchUpInside" id="uii-wI-Qvl"/>
                            </connections>
                        </button>
                        <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="z3K-EZ-Ed5">
                            <rect key="frame" x="630" y="668" width="48" height="30"/>
                            <state key="normal" title="Cancel">
                                <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
                            </state>
                            <connections>
                                <action selector="cancel:" destination="-2" eventType="touchUpInside" id="2I9-2I-AWP"/>
                            </connections>
                        </button>
                    </subviews>
                    <color key="backgroundColor" white="1" alpha="0.95000000000000007" colorSpace="custom" customColorSpace="calibratedWhite"/>
                </view>
            </subviews>
            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
            <nil key="simulatedStatusBarMetrics"/>
            <simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
        </view>
    </objects>
</document>

repo_name: fedden/RenderMan

mime_type: text/x-c++


text:
//-----------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/interappaudio/PresetSaveViewController.h
// Created by  : Steinberg, 09/2013
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

/// \cond ignore

#ifdef __OBJC__

#import <UIKit/UIKit.h>
#import <functional>

@interface PresetSaveViewController : UIViewController<UIAlertViewDelegate, UITextFieldDelegate>

- (id)initWithCallback:(std::function<void (const char* presetPath)>)callback;

@end

#endif //__OBJC__

/// \endcond


text:
//-----------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/interappaudio/AudioIO.mm
// Created by  : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#import "AudioIO.h"
#import "MidiIO.h"
#import "pluginterfaces/base/fstrdefs.h"
#import <AudioUnit/AudioUnit.h>
#import <AVFoundation/AVAudioSession.h>
#import <UIKit/UIKit.h>

#define FORCE_INLINE	__attribute__((always_inline))

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

//------------------------------------------------------------------------
static AudioBufferList* createBuffers (uint32 numChannels, uint32 maxFrames, uint32 frameSize)
{
	AudioBufferList* result = (AudioBufferList*) malloc (sizeof (AudioBufferList) + sizeof (AudioBuffer) * numChannels);
	result->mNumberBuffers = numChannels;
	for (int32 i = 0; i < numChannels; i++)
	{
		result->mBuffers[i].mDataByteSize = maxFrames * sizeof (float);
		result->mBuffers[i].mData = calloc (1, result->mBuffers[i].mDataByteSize);
		result->mBuffers[i].mNumberChannels = 1;
	}
	return result;
}

//------------------------------------------------------------------------
static void freeAudioBufferList (AudioBufferList* audioBufferList)
{
	for (uint32 i = 0; i < audioBufferList->mNumberBuffers; i++)
	{
		free (audioBufferList->mBuffers[i].mData);
	}
	free (audioBufferList);
}

//------------------------------------------------------------------------
NSString* AudioIO::kConnectionStateChange = @"AudioIO::kConnectionStateChange";

//------------------------------------------------------------------------
AudioIO::AudioIO ()
: remoteIO (0)
, graph (0)
, ioBufferList (0)
, maxFrames (4096)
, staticTempo (120.)
, interAppAudioConnected (false)
, internalState (kUninitialized)
{
	sampleRate = [[AVAudioSession sharedInstance] sampleRate];
	memset (&hostCallback, 0, sizeof (HostCallbackInfo));

	MidiIO::instance ();
}

//------------------------------------------------------------------------
AudioIO::~AudioIO ()
{
	if (ioBufferList)
		freeAudioBufferList (ioBufferList);
}

//------------------------------------------------------------------------
AudioIO* AudioIO::instance ()
{
	static AudioIO gInstance;
	return &gInstance;
}

//------------------------------------------------------------------------
tresult AudioIO::setupRemoteIO (OSType type)
{
	if (remoteIO != 0)
	{
		AudioStreamBasicDescription streamFormat = {};
		streamFormat.mChannelsPerFrame	= 2;
		streamFormat.mSampleRate		= sampleRate;
		streamFormat.mFormatID			= kAudioFormatLinearPCM;
		streamFormat.mFormatFlags		= kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;
		streamFormat.mBytesPerFrame		= streamFormat.mBytesPerPacket = sizeof(Float32);
		streamFormat.mBitsPerChannel	= 32;
		streamFormat.mFramesPerPacket	= 1;

		OSStatus status = AudioUnitSetProperty (remoteIO,
												kAudioUnitProperty_StreamFormat,
												kAudioUnitScope_Output,
												1,
												&streamFormat,
												sizeof(streamFormat));
		if (status != noErr)
			return kInternalError;

		status = AudioUnitSetProperty ( remoteIO,
										kAudioUnitProperty_StreamFormat,
										kAudioUnitScope_Input,
										0,
										&streamFormat,
										sizeof(streamFormat));
		if (status != noErr)
			return kInternalError;

		status = AudioUnitSetProperty ( remoteIO,
										kAudioUnitProperty_MaximumFramesPerSlice,
										kAudioUnitScope_Global,
										1,
										&maxFrames,
										sizeof(maxFrames));

		if (status != noErr)
			return kInternalError;

		bool needInput = (type == kAudioUnitType_RemoteGenerator || type == kAudioUnitType_RemoteInstrument) == false;
		UInt32 flag = 1;
		if (needInput)
		{
			// enable IO Input
			status = AudioUnitSetProperty  (remoteIO,
											kAudioOutputUnitProperty_EnableIO,
											kAudioUnitScope_Input,
											1,
											&flag,
											sizeof(flag));
			if (status != noErr)
				return kInternalError;
		}

		// enable IO Output
		status = AudioUnitSetProperty  (remoteIO,
										kAudioOutputUnitProperty_EnableIO,
										kAudioUnitScope_Output,
										0,
										&flag,
										sizeof(flag));
		if (status != noErr)
			return kInternalError;

		AURenderCallbackStruct renderCallback = {};
		if (needInput)
		{
			renderCallback.inputProc = inputCallbackStatic;
			renderCallback.inputProcRefCon = this;
			status = AudioUnitSetProperty (remoteIO, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 1, &renderCallback, sizeof (renderCallback));
			if (status != noErr)
				return kInternalError;
		}

		renderCallback.inputProc = renderCallbackStatic;
		renderCallback.inputProcRefCon = this;
		status = AudioUnitSetProperty (remoteIO, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, 0, &renderCallback, sizeof (renderCallback));
		if (status != noErr)
			return kInternalError;

		if (type == kAudioUnitType_RemoteInstrument || type == kAudioUnitType_RemoteMusicEffect)
		{
			AudioOutputUnitMIDICallbacks callBackStruct = {};
			callBackStruct.userData = this;
			callBackStruct.MIDIEventProc = midiEventCallbackStatic;
			status = AudioUnitSetProperty (remoteIO, kAudioOutputUnitProperty_MIDICallbacks, kAudioUnitScope_Global, 0, &callBackStruct, sizeof (callBackStruct));
			if (status != noErr)
			{
				NSLog (@"Setting MIDICallback on OutputUnit failed");
			}
		}

		if (ioBufferList)
			freeAudioBufferList (ioBufferList);
		ioBufferList = createBuffers (streamFormat.mChannelsPerFrame, maxFrames, streamFormat.mBytesPerFrame);
		if (ioBufferList == 0)
			return kOutOfMemory;

		status = AudioUnitAddPropertyListener (remoteIO, kAudioUnitProperty_IsInterAppConnected, propertyChangeStatic, this);
		status = AudioUnitAddPropertyListener (remoteIO, kAudioOutputUnitProperty_HostTransportState, propertyChangeStatic, this);

		return kResultTrue;
	}
	return kResultFalse;
}

//------------------------------------------------------------------------
tresult AudioIO::setupAUGraph (OSType type)
{
	if (graph == 0)
	{
		OSStatus status = NewAUGraph (&graph);
		if (status != noErr)
			return kInternalError;

		AudioComponentDescription iOUnitDescription;
		iOUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
		iOUnitDescription.componentFlags = 0;
		iOUnitDescription.componentFlagsMask = 0;
		iOUnitDescription.componentType = kAudioUnitType_Output;
		iOUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO;

		AUNode remoteIONode;
		status = AUGraphAddNode (graph, &iOUnitDescription, &remoteIONode);
		if (status != noErr)
			return kInternalError;
		status = AUGraphOpen(graph);
		if (status != noErr)
			return kInternalError;
		status = AUGraphNodeInfo (graph, remoteIONode, 0, &remoteIO);
		if (status != noErr)
			return kInternalError;
		return setupRemoteIO (type);
	}
	return kResultFalse;
}

//------------------------------------------------------------------------
void AudioIO::updateInterAppAudioConnectionState ()
{
	if (remoteIO)
	{
		UInt32 connected;
		UInt32 dataSize = sizeof (connected);
		OSStatus status = AudioUnitGetProperty(remoteIO, kAudioUnitProperty_IsInterAppConnected, kAudioUnitScope_Global, 0, &connected, &dataSize);
		if (status == noErr)
		{
			if (interAppAudioConnected != connected)
			{
				if (connected)
				{
					UInt32 size = sizeof (HostCallbackInfo);
					status = AudioUnitGetProperty (remoteIO, kAudioUnitProperty_HostCallbacks, kAudioUnitScope_Global, 0, &hostCallback, &size);
				}
				else
				{
					memset (&hostCallback, 0, sizeof (HostCallbackInfo));
				}
				interAppAudioConnected = connected > 0 ? true : false;
				[[NSNotificationCenter defaultCenter] postNotificationName:kConnectionStateChange object:nil];
			}
		}
	}
}

//------------------------------------------------------------------------
tresult AudioIO::init (OSType type, OSType subType, OSType manufacturer, CFStringRef name)
{
	tresult result = setupAUGraph (type);
	if (result != kResultTrue)
		return result;

	AudioComponentDescription desc = { type, subType, manufacturer, 0, 0 };
	OSStatus status = AudioOutputUnitPublish (&desc, name, 0, remoteIO);
	if (status != noErr)
	{
		NSLog (@"AudioOutputUnitPublish failed with status:%d", (int)status);
	}
	internalState = kInitialized;

	return result;
}

//------------------------------------------------------------------------
void AudioIO::setAudioSessionActive (bool state)
{
	NSError* error;

	AVAudioSession *session = [AVAudioSession sharedInstance];
	[session setPreferredSampleRate: sampleRate error:&error];
	[session setCategory: AVAudioSessionCategoryPlayback withOptions: AVAudioSessionCategoryOptionMixWithOthers error:&error];
	[session setActive:(state ? YES : NO) error:&error];
}

//------------------------------------------------------------------------
tresult AudioIO::start ()
{
	if (internalState == kInitialized)
	{
		bool appIsActive = [UIApplication sharedApplication].applicationState == UIApplicationStateActive;
		if (!(appIsActive || interAppAudioConnected))
		{
			return kResultFalse;
		}
		setAudioSessionActive (true);

		Boolean graphInitialized = true;
		OSStatus status = AUGraphIsInitialized (graph, &graphInitialized);
		if (status != noErr)
			return kInternalError;

		if (graphInitialized == false)
		{
			status = AUGraphInitialize (graph);
			if (status != noErr)
				return kInternalError;
			updateInterAppAudioConnectionState ();
		}

		for (auto processor : audioProcessors)
		{
			processor->willStartAudio (this);
		}
		status = AUGraphStart (graph);
		if (status == noErr)
		{
			internalState = kStarted;
			updateInterAppAudioConnectionState ();
			return kResultTrue;
		}
		return kInternalError;
	}

	return kResultFalse;
}

//------------------------------------------------------------------------
tresult AudioIO::stop ()
{
	if (internalState == kStarted)
	{
		if (AUGraphStop (graph) == noErr)
		{
			for (auto processor : audioProcessors)
			{
				processor->didStopAudio (this);
			}
			internalState = kInitialized;
			if (interAppAudioConnected == false)
				setAudioSessionActive (false);
			return kResultTrue;
		}
	}
	return kResultFalse;
}

//------------------------------------------------------------------------
tresult AudioIO::addProcessor (IAudioIOProcessor* processor)
{
	if (internalState == kInitialized)
	{
		audioProcessors.push_back (processor);
		MidiIO::instance ().addProcessor (processor);
		return kResultTrue;
	}
	return kResultFalse;
}

//------------------------------------------------------------------------
tresult AudioIO::removeProcessor (IAudioIOProcessor* processor)
{
	if (internalState == kInitialized)
	{
		auto it = std::find (audioProcessors.begin (), audioProcessors.end (), processor);
		if (it != audioProcessors.end ())
		{
			audioProcessors.erase (it);
			MidiIO::instance ().removeProcessor (processor);
			return kResultTrue;
		}
	}
	return kResultFalse;
}

//------------------------------------------------------------------------
bool AudioIO::switchToHost ()
{
	if (remoteIO && interAppAudioConnected)
	{
        CFURLRef instrumentUrl;
        UInt32 dataSize = sizeof(instrumentUrl);
        OSStatus result = AudioUnitGetProperty (remoteIO, kAudioUnitProperty_PeerURL, kAudioUnitScope_Global, 0, &instrumentUrl, &dataSize);
        if (result == noErr)
		{
            [[UIApplication sharedApplication] openURL:(__bridge NSURL*)instrumentUrl];
			return true;
		}
	}
	return false;
}

//------------------------------------------------------------------------
bool AudioIO::sendRemoteControlEvent (AudioUnitRemoteControlEvent event)
{
	if (remoteIO && interAppAudioConnected)
	{
		UInt32 controlEvent = event;
		UInt32 dataSize = sizeof (controlEvent);
		OSStatus status = AudioUnitSetProperty (remoteIO, kAudioOutputUnitProperty_RemoteControlToHost, kAudioUnitScope_Global, 0, &controlEvent, dataSize);
		return status == noErr;
	}
	return false;
}

//------------------------------------------------------------------------
UIImage* AudioIO::getHostIcon ()
{
	if (remoteIO && interAppAudioConnected)
	{
		return AudioOutputUnitGetHostIcon (remoteIO, 128);
	}
	return nil;
}

//------------------------------------------------------------------------
bool AudioIO::getBeatAndTempo (Float64& beat, Float64& tempo)
{
	if (hostCallback.beatAndTempoProc)
	{
		if (hostCallback.beatAndTempoProc (hostCallback.hostUserData, &beat, &tempo) == noErr)
			return true;
	}
	tempo = staticTempo;
	beat = 0;
	return true;
}

//------------------------------------------------------------------------
bool AudioIO::getMusicalTimeLocation (UInt32& deltaSampleOffset, Float32& timeSigNumerator, UInt32& timeSigDenominator, Float64& downBeat)
{
	if (hostCallback.musicalTimeLocationProc)
	{
		if (hostCallback.musicalTimeLocationProc (hostCallback.hostUserData, &deltaSampleOffset, &timeSigNumerator, &timeSigDenominator, &downBeat) == noErr)
			return true;
	}
	return false;
}

//------------------------------------------------------------------------
bool AudioIO::getTransportState (Boolean& isPlaying, Boolean& isRecording, Boolean& transportStateChanged, Float64& sampleInTimeLine, Boolean& isCycling, Float64& cycleStartBeat, Float64& cycleEndBeat)
{
	if (hostCallback.transportStateProc2)
	{
		if (hostCallback.transportStateProc2 (hostCallback.hostUserData, &isPlaying, &isRecording, &transportStateChanged, &sampleInTimeLine, &isCycling, &cycleStartBeat, &cycleEndBeat) == noErr)
			return true;
	}
	return false;
}

//------------------------------------------------------------------------
FORCE_INLINE void AudioIO::remoteIOPropertyChanged (AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement)
{
	if (inID == kAudioUnitProperty_IsInterAppConnected)
	{
		bool wasConnected = interAppAudioConnected;
		updateInterAppAudioConnectionState ();
		if (wasConnected != interAppAudioConnected)
		{
			stop ();
			start ();
		}
	}
}

//------------------------------------------------------------------------
FORCE_INLINE OSStatus AudioIO::renderCallback (AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
	if (ioData->mNumberBuffers == ioBufferList->mNumberBuffers)
	{
		for (uint32 i = 0; i < ioData->mNumberBuffers; i++)
		{
			memcpy (ioData->mBuffers[i].mData, ioBufferList->mBuffers[i].mData, ioData->mBuffers[i].mDataByteSize);
		}
		bool outputIsSilence = ioActionFlags ? *ioActionFlags & kAudioUnitRenderAction_OutputIsSilence : false;
		for (auto processor : audioProcessors)
		{
			outputIsSilence = false;
			processor->process (inTimeStamp, inBusNumber, inNumberFrames, ioData, outputIsSilence, this);
		}
		if (ioActionFlags)
		{
			*ioActionFlags = outputIsSilence ? kAudioUnitRenderAction_OutputIsSilence : 0;
		}
	}
	return noErr;
}

//------------------------------------------------------------------------
FORCE_INLINE OSStatus AudioIO::inputCallback (AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
	OSStatus status = AudioUnitRender (remoteIO, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioBufferList);
	return status;
}

//------------------------------------------------------------------------
FORCE_INLINE void AudioIO::midiEventCallback (UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame)
{
	for (auto processor : audioProcessors)
	{
		processor->onMIDIEvent (inStatus, inData1, inData2, inOffsetSampleFrame, true);
	}
}

//------------------------------------------------------------------------
OSStatus AudioIO::inputCallbackStatic (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
	AudioIO* io = (AudioIO*)inRefCon;
	return io->inputCallback (ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData);
}

//------------------------------------------------------------------------
OSStatus AudioIO::renderCallbackStatic (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
{
	AudioIO* io = (AudioIO*)inRefCon;
	return io->renderCallback (ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData);
}

//------------------------------------------------------------------------
void AudioIO::propertyChangeStatic (void *inRefCon, AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement)
{
	AudioIO* audioIO = (AudioIO*)inRefCon;
	audioIO->remoteIOPropertyChanged(inID, inScope, inElement);
}

//------------------------------------------------------------------------
void AudioIO::midiEventCallbackStatic (void *inRefCon, UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame)
{
	AudioIO* audioIO = (AudioIO*)inRefCon;
	audioIO->midiEventCallback(inStatus, inData1, inData2, inOffsetSampleFrame);
}

}}}


text:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="4510" systemVersion="12F37" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PresetSaveViewController">
            <connections>
                <outlet property="containerView" destination="SIT-sP-q5k" id="Pam-4d-cjt"/>
                <outlet property="presetName" destination="4mQ-Y5-WZh" id="MJT-bn-9QR"/>
                <outlet property="view" destination="2" id="0Me-yB-Sts"/>
            </connections>
        </placeholder>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <view opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="2">
            <rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
            <subviews>
                <view opaque="NO" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SIT-sP-q5k">
                    <rect key="frame" x="256" y="192" width="512" height="104"/>
                    <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                    <subviews>
                        <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Preset Name :" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EGr-Dl-Wf3">
                            <rect key="frame" x="20" y="20" width="119" height="21"/>
                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                            <fontDescription key="fontDescription" type="system" pointSize="17"/>
                            <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
                            <nil key="highlightedColor"/>
                        </label>
                        <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="4mQ-Y5-WZh">
                            <rect key="frame" x="147" y="16" width="345" height="30"/>
                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
                            <textInputTraits key="textInputTraits"/>
                            <connections>
                                <outlet property="delegate" destination="-1" id="LIF-nc-eQa"/>
                            </connections>
                        </textField>
                        <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="v51-mb-0Tu">
                            <rect key="frame" x="446" y="71" width="46" height="30"/>
                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                            <fontDescription key="fontDescription" type="system" pointSize="17"/>
                            <state key="normal" title="Save"/>
                            <connections>
                                <action selector="save:" destination="-1" eventType="touchUpInside" id="J1n-Ix-DQA"/>
                            </connections>
                        </button>
                        <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SBt-7v-tI9">
                            <rect key="frame" x="20" y="71" width="54" height="30"/>
                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                            <fontDescription key="fontDescription" type="system" pointSize="17"/>
                            <state key="normal" title="Cancel">
                                <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
                            </state>
                            <connections>
                                <action selector="cancel:" destination="-1" eventType="touchUpInside" id="ibs-yW-oi5"/>
                            </connections>
                        </button>
                    </subviews>
                    <color key="backgroundColor" white="1" alpha="0.95000000000000007" colorSpace="custom" customColorSpace="calibratedWhite"/>
                </view>
            </subviews>
            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
            <simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
        </view>
    </objects>
</document>


text:
//-----------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/interappaudio/VST3Editor.h
// Created by  : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

/// \cond ignore

#import "base/source/fobject.h"
#import "pluginterfaces/gui/iplugview.h"
#import <UIKit/UIKit.h>

namespace Steinberg {
namespace Vst {
class IEditController;

namespace InterAppAudio {

//------------------------------------------------------------------------
class VST3Editor : public FObject, public IPlugFrame
{
public:
//------------------------------------------------------------------------
	VST3Editor ();
	virtual ~VST3Editor ();

	bool init (const CGRect& frame);
	bool attach (IEditController* editController);

	UIViewController* getViewController () const { return viewController; }

	OBJ_METHODS(VST3Editor, FObject)
	REFCOUNT_METHODS(FObject)
	DEFINE_INTERFACES
		DEF_INTERFACE(IPlugFrame)
	END_DEFINE_INTERFACES(FObject)
protected:

	// IPlugFrame
	tresult PLUGIN_API resizeView (IPlugView* view, ViewRect* newSize) override;

	IPlugView* plugView;
	UIViewController* viewController;
};

//------------------------------------------------------------------------
} // namespace InterAppAudio
} // namespace Vst
} // namespace Steinberg

/// \endcond


text:
//-----------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/interappaudio/AudioIO.h
// Created by  : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

/// \cond ignore

#include <AudioUnit/AUComponent.h>
#include <AudioToolbox/AudioToolbox.h>
#include "pluginterfaces/base/funknown.h"
#include "pluginterfaces/vst/vsttypes.h"
#include <vector>

#ifndef __OBJC__
struct UIImage;
struct NSString;
#endif

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

class AudioIO;

//------------------------------------------------------------------------
class IMidiProcessor
{
public:
	virtual void onMIDIEvent (UInt32 status, UInt32 data1, UInt32 data2, UInt32 sampleOffset, bool withinRealtimeThread) = 0;
};

//------------------------------------------------------------------------
class IAudioIOProcessor : public IMidiProcessor
{
public:
	virtual void willStartAudio (AudioIO* audioIO) = 0;
	virtual void didStopAudio (AudioIO* audioIO) = 0;

	virtual void process (const AudioTimeStamp* timeStamp, UInt32 busNumber, UInt32 numFrames, AudioBufferList* ioData, bool& outputIsSilence, AudioIO* audioIO) = 0;
};

//------------------------------------------------------------------------
class AudioIO
{
public:
	static AudioIO* instance ();

	tresult init (OSType type, OSType subType, OSType manufacturer, CFStringRef name);

	bool switchToHost ();
	bool sendRemoteControlEvent (AudioUnitRemoteControlEvent event);
	UIImage* getHostIcon ();

	tresult start ();
	tresult stop ();

	tresult addProcessor (IAudioIOProcessor* processor);
	tresult removeProcessor (IAudioIOProcessor* processor);

	// accessors
	AudioUnit getRemoteIO () const { return remoteIO; }
	SampleRate getSampleRate () const { return sampleRate; }
	bool getInterAppAudioConnected () const { return interAppAudioConnected; }

	// host context information
	bool getBeatAndTempo (Float64& beat, Float64& tempo);
	bool getMusicalTimeLocation (UInt32& deltaSampleOffset, Float32& timeSigNumerator, UInt32& timeSigDenominator, Float64& downBeat);
	bool getTransportState (Boolean& isPlaying, Boolean& isRecording, Boolean& transportStateChanged, Float64& sampleInTimeLine, Boolean& isCycling, Float64& cycleStartBeat, Float64& cycleEndBeat);

	void setStaticFallbackTempo (Float64 tempo) {staticTempo = tempo; }
	Float64 getStaticFallbackTempo () const { return staticTempo; }

	static NSString* kConnectionStateChange;
//------------------------------------------------------------------------
protected:
	AudioIO ();
	~AudioIO ();

	static OSStatus inputCallbackStatic (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
	static OSStatus renderCallbackStatic (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
	static void propertyChangeStatic (void *inRefCon, AudioUnit inUnit, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement);
	static void midiEventCallbackStatic (void *inRefCon, UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame);

	OSStatus inputCallback (AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
	OSStatus renderCallback (AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
	void midiEventCallback (UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame);

	void remoteIOPropertyChanged (AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement);

	void setAudioSessionActive (bool state);
	tresult setupRemoteIO (OSType type);
	tresult setupAUGraph (OSType type);
	void updateInterAppAudioConnectionState ();

	AudioUnit remoteIO;
	AUGraph graph;
	AudioBufferList* ioBufferList;
	HostCallbackInfo hostCallback;
	UInt32 maxFrames;
	Float64 staticTempo;
	SampleRate sampleRate;
	bool interAppAudioConnected;
	std::vector<IAudioIOProcessor*> audioProcessors;

	enum InternalState {
		kUninitialized,
		kInitialized,
		kStarted,
	};
	InternalState internalState;
};

//------------------------------------------------------------------------
} // namespace InterAppAudio
} // namespace Vst
} // namespace Steinberg

/// \endcond


text:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="4510" systemVersion="12F45" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SettingsViewController">
            <connections>
                <outlet property="containerView" destination="RNQ-ag-wXs" id="Snq-jH-mGX"/>
                <outlet property="midiOnSwitch" destination="RUK-3J-c68" id="fsn-qn-B1b"/>
                <outlet property="tempoView" destination="7Wa-1f-ZEh" id="aAo-kk-UXa"/>
                <outlet property="view" destination="2" id="3"/>
            </connections>
        </placeholder>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <view opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="2">
            <rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
            <subviews>
                <view opaque="NO" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RNQ-ag-wXs">
                    <rect key="frame" x="272" y="266" width="481" height="236"/>
                    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                    <subviews>
                        <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RUK-3J-c68">
                            <rect key="frame" x="165" y="92" width="51" height="31"/>
                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                            <connections>
                                <action selector="enableMidi:" destination="-1" eventType="valueChanged" id="W1y-Cl-XZT"/>
                            </connections>
                        </switch>
                        <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Enable MIDI Input" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uh8-Ad-fHW">
                            <rect key="frame" x="20" y="97" width="137" height="21"/>
                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                            <fontDescription key="fontDescription" type="system" pointSize="17"/>
                            <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
                            <nil key="highlightedColor"/>
                        </label>
                        <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gsH-Se-9I1">
                            <rect key="frame" x="220" y="186" width="40" height="30"/>
                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                            <state key="normal" title="Close">
                                <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
                            </state>
                            <connections>
                                <action selector="close:" destination="-1" eventType="touchUpInside" id="8fR-1E-VU7"/>
                            </connections>
                        </button>
                        <pickerView contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7Wa-1f-ZEh">
                            <rect key="frame" x="329" y="0.0" width="86" height="216"/>
                            <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
                            <connections>
                                <outlet property="dataSource" destination="-1" id="kTa-mw-jgX"/>
                                <outlet property="delegate" destination="-1" id="afl-U5-l43"/>
                            </connections>
                        </pickerView>
                        <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="BPM" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ccr-8n-eGh">
                            <rect key="frame" x="423" y="97" width="38" height="21"/>
                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                            <fontDescription key="fontDescription" type="system" pointSize="17"/>
                            <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
                            <nil key="highlightedColor"/>
                        </label>
                        <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Tempo" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jiY-aT-q6h">
                            <rect key="frame" x="267" y="97" width="52" height="21"/>
                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                            <fontDescription key="fontDescription" type="system" pointSize="17"/>
                            <nil key="highlightedColor"/>
                        </label>
                    </subviews>
                    <color key="backgroundColor" white="1" alpha="0.95000000000000007" colorSpace="custom" customColorSpace="calibratedWhite"/>
                </view>
            </subviews>
            <color key="backgroundColor" white="1" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
            <simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
        </view>
    </objects>
</document>


text:
//-----------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/interappaudio/PresetManager.h
// Created by  : Steinberg, 10/2013
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "VST3Plugin.h"
#include "pluginterfaces/vst/ivstinterappaudio.h"
#include "base/source/fstring.h"

#if __OBJC__
@class NSArray, PresetBrowserViewController, PresetSaveViewController;
#else
struct NSArray;
struct PresetBrowserViewController;
struct PresetSaveViewController;
#endif

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

class PresetManager : public FObject, public IInterAppAudioPresetManager
{
public:
	PresetManager (VST3Plugin* plugin, const TUID& cid);

	tresult PLUGIN_API runLoadPresetBrowser () override;
	tresult PLUGIN_API runSavePresetBrowser () override;
	tresult PLUGIN_API loadNextPreset () override;
	tresult PLUGIN_API loadPreviousPreset () override;

	DEFINE_INTERFACES
		DEF_INTERFACE(IInterAppAudioPresetManager)
	END_DEFINE_INTERFACES(FObject)
	REFCOUNT_METHODS(FObject)

private:
	enum PresetPathType {
		kFactory,
		kUser
	};
	NSArray* getPresetPaths (PresetPathType type);

	tresult loadPreset (bool next);
	tresult loadPreset (const char* path);
	void savePreset (const char* path);

	VST3Plugin* plugin;
	PresetBrowserViewController* visiblePresetBrowserViewController;
	PresetSaveViewController* visibleSavePresetViewController;
	FUID cid;
	String lastPreset;
};

//------------------------------------------------------------------------
} // namespace InterAppAudio
} // namespace Vst
} // namespace Steinberg


text:
//-----------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/interappaudio/HostApp.h
// Created by  : Steinberg, 08/2013.
// Description : VST 3 InterAppAudio
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

/// \cond ignore

#import "base/source/fobject.h"
#import "public.sdk/source/vst/hosting/hostclasses.h"
#import "pluginterfaces/vst/ivstinterappaudio.h"

namespace Steinberg {
namespace Vst {
namespace InterAppAudio {

class VST3Plugin;

//-----------------------------------------------------------------------------
class InterAppAudioHostApp : public FObject, public HostApplication, public IInterAppAudioHost
{
public:
//-----------------------------------------------------------------------------
	static InterAppAudioHostApp* instance ();

	void setPlugin (VST3Plugin* plugin);
	VST3Plugin* getPlugin () const { return plugin; }

//-----------------------------------------------------------------------------
//	IInterAppAudioHost
	tresult PLUGIN_API getScreenSize (ViewRect* size, float* scale) override;
	tresult PLUGIN_API connectedToHost () override;
	tresult PLUGIN_API switchToHost () override;
	tresult PLUGIN_API sendRemoteControlEvent (uint32 event) override;
	tresult PLUGIN_API getHostIcon (void** icon) override;
	tresult PLUGIN_API scheduleEventFromUI (Event& event) override;
	IInterAppAudioPresetManager* PLUGIN_API createPresetManager (const TUID& cid) override;
	tresult PLUGIN_API showSettingsView () override;

//-----------------------------------------------------------------------------
//	HostApplication
	tresult PLUGIN_API getName (String128 name) override;

	OBJ_METHODS(InterAppAudioHostApp, FObject)
	REFCOUNT_METHODS(FObject)
	DEFINE_INTERFACES
		DEF_INTERFACE(IHostApplication)
		DEF_INTERFACE(IInterAppAudioHost)
	END_DEFINE_INTERFACES(FObject)
protected:
	InterAppAudioHostApp ();

	VST3Plugin* plugin;
};

//------------------------------------------------------------------------
} // namespace InterAppAudio
} // namespace Vst
} // namespace Steinberg

/// \endcond


text:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="EHf-IW-A2E">
            <objects>
                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
                        <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="53" y="375"/>
        </scene>
    </scenes>
</document>


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : Common Base Classes
// Filename    : public.sdk/source/common/pluginview.h
// Created by  : Steinberg, 01/2004
// Description : Plug-In View Implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/gui/iplugview.h"
#include "base/source/fobject.h"

namespace Steinberg {

//------------------------------------------------------------------------
/** Plug-In view default implementation.
\ingroup sdkBase
Can be used as base class for an IPlugView implementation. */
//------------------------------------------------------------------------
class CPluginView: public FObject,
	               public IPlugView
{
public:
//------------------------------------------------------------------------
	CPluginView (const ViewRect* rect = 0);
	virtual ~CPluginView ();

	/** Returns its current frame rectangle. */
	const ViewRect& getRect () const	{ return rect; }

	/** Sets a new frame rectangle. */
	void setRect (const ViewRect& r)	{ rect = r; }

	/** Checks if this view is attached to its parent view. */
	bool isAttached () const			{ return systemWindow != 0; }

	/** Calls when this view will be attached to its parent view. */
	virtual void attachedToParent () {}

	/** Calls when this view will be removed from its parent view. */
	virtual void removedFromParent () {}

	//---from IPlugView-------
	tresult PLUGIN_API isPlatformTypeSupported (FIDString type) SMTG_OVERRIDE;
	tresult PLUGIN_API attached (void* parent, FIDString type) SMTG_OVERRIDE;
	tresult PLUGIN_API removed () SMTG_OVERRIDE;

	tresult PLUGIN_API onWheel (float /*distance*/) SMTG_OVERRIDE { return kResultFalse; }
	tresult PLUGIN_API onKeyDown (char16 /*key*/, int16 /*keyMsg*/, int16 /*modifiers*/) SMTG_OVERRIDE { return kResultFalse; }
	tresult PLUGIN_API onKeyUp (char16 /*key*/, int16 /*keyMsg*/, int16 /*modifiers*/) SMTG_OVERRIDE { return kResultFalse; }
	tresult PLUGIN_API getSize (ViewRect* size) SMTG_OVERRIDE;
	tresult PLUGIN_API onSize (ViewRect* newSize) SMTG_OVERRIDE;

	tresult PLUGIN_API onFocus (TBool /*state*/) SMTG_OVERRIDE { return kResultFalse; }
	tresult PLUGIN_API setFrame (IPlugFrame* frame) SMTG_OVERRIDE { plugFrame = frame; return kResultTrue; }

	tresult PLUGIN_API canResize () SMTG_OVERRIDE { return kResultFalse; }
	tresult PLUGIN_API checkSizeConstraint (ViewRect* /*rect*/) SMTG_OVERRIDE { return kResultFalse; }

	//---Interface------
	OBJ_METHODS (CPluginView, FObject)
	DEFINE_INTERFACES
		DEF_INTERFACE (IPlugView)
	END_DEFINE_INTERFACES (FObject)
	REFCOUNT_METHODS(FObject)
//------------------------------------------------------------------------
protected:
	ViewRect rect;
	void* systemWindow;
	IPlugFrame* plugFrame;
};

}	// namespace


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : Common Base Classes
// Filename    : public.sdk/source/common/pluginview.cpp
// Created by  : Steinberg, 01/2004
// Description : Plug-In View Implementation
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "pluginview.h"

namespace Steinberg {

//------------------------------------------------------------------------
//  CPluginView implementation
//------------------------------------------------------------------------
CPluginView::CPluginView (const ViewRect* _rect)
: rect (0, 0, 0, 0)
, systemWindow (0)
, plugFrame (0)
{
	//TODO FUNKNOWN_CTOR
	if (_rect)
		rect = *_rect;
}

//------------------------------------------------------------------------
CPluginView::~CPluginView ()
{
	//TODO FUNKNOWN_DTOR
}

//------------------------------------------------------------------------
// TODO IMPLEMENT_REFCOUNT (CPluginView)

//------------------------------------------------------------------------
/* TODO
tresult PLUGIN_API CPluginView::queryInterface (const char* iid, void** obj)
{
	QUERY_INTERFACE (iid, obj, Steinberg::FUnknown::iid, IPlugView)
	QUERY_INTERFACE (iid, obj, Steinberg::IPlugView::iid,  IPlugView)
	*obj = 0;
	return kNoInterface;
}*/

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginView::isPlatformTypeSupported (FIDString /*type*/)
{
	return kNotImplemented;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginView::attached (void* parent, FIDString /*type*/)
{
	systemWindow = parent;

	attachedToParent ();
	return kResultOk;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginView::removed ()
{
	systemWindow = 0;

	removedFromParent ();
	return kResultOk;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginView::onSize (ViewRect* newSize)
{
	if (newSize)
		rect = *newSize;
	return kResultTrue;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginView::getSize (ViewRect* size)
{
	if (size)
	{
		*size = rect;
		return kResultTrue;
	}
	return kInvalidArgument;
}

} // end of namespace


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : Common Classes
// Filename    : public.sdk/source/common/memorystream.h
// Created by  : Steinberg, 03/2008
// Description : IBStream Implementation for memory blocks
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/base/ibstream.h"

namespace Steinberg {

//------------------------------------------------------------------------
/** Memory based Stream for IBStream implementation (using malloc).
\ingroup sdkBase
*/
//------------------------------------------------------------------------
class MemoryStream : public IBStream
{
public:
	//------------------------------------------------------------------------
	MemoryStream ();
	MemoryStream (void* memory, TSize memorySize); 	///< reuse a given memory without getting ownership
	virtual ~MemoryStream ();

	//---IBStream---------------------------------------
	virtual tresult PLUGIN_API read  (void* buffer, int32 numBytes, int32* numBytesRead) SMTG_OVERRIDE;
	virtual tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten) SMTG_OVERRIDE;
	virtual tresult PLUGIN_API seek  (int64 pos, int32 mode, int64* result) SMTG_OVERRIDE;
	virtual tresult PLUGIN_API tell  (int64* pos) SMTG_OVERRIDE;

	TSize getSize ();		///< returns the current memory size
	void setSize (TSize size);	///< set the memory size, a realloc will occur if memory already used
	char* getData ();		///< returns the memory pointer
	char* detachData ();	///< returns the memory pointer and give up ownership
	bool truncate ();		///< realloc to the current use memory size if needed
	bool truncateToCursor ();	///< truncate memory at current cursor position

	//------------------------------------------------------------------------
	DECLARE_FUNKNOWN_METHODS
protected:
	char* memory;				// memory block
	TSize memorySize;			// size of the memory block
	TSize size;					// size of the stream
	int64 cursor;				// stream pointer
	bool ownMemory;				// stream has allocated memory itself
	bool allocationError;       // stream invalid
};

} // namespace


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
//
// Category    : Common Classes
// Filename    : public.sdk/source/common/memorystream.cpp
// Created by  : Steinberg, 03/2008
// Description : IBStream Implementation for memory blocks
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "memorystream.h"
#include "pluginterfaces/base/futils.h"
#include <stdlib.h>

namespace Steinberg {

//-----------------------------------------------------------------------------
IMPLEMENT_FUNKNOWN_METHODS (MemoryStream, IBStream, IBStream::iid)
static const TSize kMemGrowAmount = 4096;

//-----------------------------------------------------------------------------
MemoryStream::MemoryStream (void* data, TSize length)
: memory ((char*)data)
, memorySize (length)
, size (length)
, cursor (0)
, ownMemory (false)
, allocationError (false)
{
	FUNKNOWN_CTOR
}

//-----------------------------------------------------------------------------
MemoryStream::MemoryStream ()
: memory (nullptr)
, memorySize (0)
, size (0)
, cursor (0)
, ownMemory (true)
, allocationError (false)
{
	FUNKNOWN_CTOR
}

//-----------------------------------------------------------------------------
MemoryStream::~MemoryStream ()
{
	if (ownMemory && memory)
		::free (memory);

	FUNKNOWN_DTOR
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API MemoryStream::read (void* data, int32 numBytes, int32* numBytesRead)
{
	if (memory == nullptr)
	{
		if (allocationError)
			return kOutOfMemory;
		numBytes = 0;
	}
	else
	{
		// Does read exceed size ?
		if (cursor + numBytes > size)
		{
			int32 maxBytes = int32 (size - cursor);

			// Has length become zero or negative ?
			if (maxBytes <= 0)
			{
				cursor = size;
				numBytes = 0;
			}
			else
				numBytes = maxBytes;
		}

		if (numBytes)
		{
			memcpy (data, &memory[cursor], numBytes);
			cursor += numBytes;
		}
	}

	if (numBytesRead)
		*numBytesRead = numBytes;

	return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API MemoryStream::write (void* buffer, int32 numBytes, int32* numBytesWritten)
{
	if (allocationError)
		return kOutOfMemory;
	if (buffer == nullptr)
		return kInvalidArgument;

	// Does write exceed size ?
	TSize requiredSize = cursor + numBytes;
	if (requiredSize > size)
	{
		if (requiredSize > memorySize)
			setSize (requiredSize);
		else
			size = requiredSize;
	}

	// Copy data
	if (memory && cursor >= 0 && numBytes > 0)
	{
		memcpy (&memory[cursor], buffer, numBytes);
		// Update cursor
		cursor += numBytes;
	}
	else
		numBytes = 0;

	if (numBytesWritten)
		*numBytesWritten = numBytes;

	return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API MemoryStream::seek (int64 pos, int32 mode, int64* result)
{
	switch (mode)
	{
		case kIBSeekSet:
			cursor = pos;
			break;
		case kIBSeekCur:
			cursor = cursor + pos;
			break;
		case kIBSeekEnd:
			cursor = size + pos;
			break;
	}

	if (ownMemory == false)
		if (cursor > memorySize)
			cursor = memorySize;

	if (result)
		*result = cursor;

	return kResultTrue;
}

//-----------------------------------------------------------------------------
tresult PLUGIN_API MemoryStream::tell  (int64* pos)
{
	if (!pos)
		return kInvalidArgument;

	*pos = cursor;
	return kResultTrue;
}

//------------------------------------------------------------------------
TSize MemoryStream::getSize ()
{
	return size;
}

//------------------------------------------------------------------------
void MemoryStream::setSize (TSize s)
{
	if (s <= 0)
	{
		if (ownMemory && memory)
			free (memory);

		memory = nullptr;
		memorySize = 0;
		size = 0;
		cursor = 0;
		return;
	}

	TSize newMemorySize = (((Max (memorySize, s) - 1) / kMemGrowAmount) + 1) * kMemGrowAmount;
	if (newMemorySize == memorySize)
	{
		size = s;
		return;
	}

	if (memory && ownMemory == false)
	{
		allocationError = true;
		return;
	}

	ownMemory = true;
	char* newMemory = nullptr;

	if (memory)
	{
		newMemory = (char*)realloc (memory, (size_t)newMemorySize);
		if (newMemory == nullptr && newMemorySize > 0)
		{
			newMemory = (char*)malloc ((size_t)newMemorySize);
			if (newMemory)
			{
				memcpy (newMemory, memory, (size_t)Min (newMemorySize, memorySize));
				free (memory);
			}
		}
	}
	else
		newMemory = (char*)malloc ((size_t)newMemorySize);

	if (newMemory == nullptr)
	{
		if (newMemorySize > 0)
			allocationError = true;

		memory = nullptr;
		memorySize = 0;
		size = 0;
		cursor = 0;
	}
	else
	{
		memory = newMemory;
		memorySize = newMemorySize;
		size = s;
	}
}

//------------------------------------------------------------------------
char* MemoryStream::getData ()
{
	return memory;
}

//------------------------------------------------------------------------
char* MemoryStream::detachData ()
{
	if (ownMemory)
	{
		char* result = memory;
		memory = nullptr;
		memorySize = 0;
		size = 0;
		cursor = 0;
		return result;
	}
	return nullptr;
}

//------------------------------------------------------------------------
bool MemoryStream::truncate ()
{
	if (ownMemory == false)
		return false;

	if (memorySize == size)
		return true;

	memorySize = size;

	if (memorySize == 0)
	{
		if (memory)
		{
			free (memory);
			memory = nullptr;
		}
	}
	else
	{
		if (memory)
		{
			char* newMemory = (char*)realloc (memory, (size_t)memorySize);
			if (newMemory)
				memory = newMemory;
		}
	}
	return true;
}

//------------------------------------------------------------------------
bool MemoryStream::truncateToCursor ()
{
	size = cursor;
	return truncate ();
}

} // namespace


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_graphics/juce_graphics.mm>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_data_structures/juce_data_structures.cpp>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_events/juce_events.cpp>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_audio_formats/juce_audio_formats.mm>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

    There's a section below where you can add your own custom code safely, and the
    Projucer will preserve the contents of that block, but the best way to change
    any of these definitions is by using the Projucer's project settings.

    Any commented-out settings will assume their default values.

*/

#pragma once

//==============================================================================
// [BEGIN_USER_CODE_SECTION]

// (You can add your own code in this section, and the Projucer will not overwrite it)

// [END_USER_CODE_SECTION]

/*
  ==============================================================================

   In accordance with the terms of the JUCE 5 End-Use License Agreement, the
   JUCE Code in SECTION A cannot be removed, changed or otherwise rendered
   ineffective unless you have a JUCE Indie or Pro license, or are using JUCE
   under the GPL v3 license.

   End User License Agreement: www.juce.com/juce-5-licence
  ==============================================================================
*/

// BEGIN SECTION A

#ifndef JUCE_DISPLAY_SPLASH_SCREEN
 #define JUCE_DISPLAY_SPLASH_SCREEN 0
#endif

#ifndef JUCE_REPORT_APP_USAGE
 #define JUCE_REPORT_APP_USAGE 0
#endif

// END SECTION A

#define JUCE_USE_DARK_SPLASH_SCREEN 1

//==============================================================================
#define JUCE_MODULE_AVAILABLE_juce_audio_basics          1
#define JUCE_MODULE_AVAILABLE_juce_audio_devices         1
#define JUCE_MODULE_AVAILABLE_juce_audio_formats         1
#define JUCE_MODULE_AVAILABLE_juce_audio_processors      1
#define JUCE_MODULE_AVAILABLE_juce_core                  1
#define JUCE_MODULE_AVAILABLE_juce_cryptography          1
#define JUCE_MODULE_AVAILABLE_juce_data_structures       1
#define JUCE_MODULE_AVAILABLE_juce_events                1
#define JUCE_MODULE_AVAILABLE_juce_graphics              1
#define JUCE_MODULE_AVAILABLE_juce_gui_basics            1
#define JUCE_MODULE_AVAILABLE_juce_gui_extra             1
#define JUCE_MODULE_AVAILABLE_juce_opengl                1
#define JUCE_MODULE_AVAILABLE_juce_video                 1

#define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1

//==============================================================================
// juce_audio_devices flags:

#ifndef    JUCE_ASIO
 //#define JUCE_ASIO 1
#endif

#ifndef    JUCE_WASAPI
 //#define JUCE_WASAPI 1
#endif

#ifndef    JUCE_WASAPI_EXCLUSIVE
 //#define JUCE_WASAPI_EXCLUSIVE 1
#endif

#ifndef    JUCE_DIRECTSOUND
 //#define JUCE_DIRECTSOUND 1
#endif

#ifndef    JUCE_ALSA
 //#define JUCE_ALSA 1
#endif

#ifndef    JUCE_JACK
 //#define JUCE_JACK 1
#endif

#ifndef    JUCE_USE_ANDROID_OPENSLES
 //#define JUCE_USE_ANDROID_OPENSLES 1
#endif

#ifndef    JUCE_USE_WINRT_MIDI
 //#define JUCE_USE_WINRT_MIDI 1
#endif

//==============================================================================
// juce_audio_formats flags:

#ifndef    JUCE_USE_FLAC
 //#define JUCE_USE_FLAC 1
#endif

#ifndef    JUCE_USE_OGGVORBIS
 //#define JUCE_USE_OGGVORBIS 1
#endif

#ifndef    JUCE_USE_MP3AUDIOFORMAT
 //#define JUCE_USE_MP3AUDIOFORMAT 1
#endif

#ifndef    JUCE_USE_LAME_AUDIO_FORMAT
 //#define JUCE_USE_LAME_AUDIO_FORMAT 1
#endif

#ifndef    JUCE_USE_WINDOWS_MEDIA_FORMAT
 //#define JUCE_USE_WINDOWS_MEDIA_FORMAT 1
#endif

//==============================================================================
// juce_audio_processors flags:

#ifndef    JUCE_PLUGINHOST_VST
 #define   JUCE_PLUGINHOST_VST 1
#endif

#ifndef    JUCE_PLUGINHOST_VST3
 #define   JUCE_PLUGINHOST_VST3 1
#endif

#ifndef    JUCE_PLUGINHOST_AU
 #define   JUCE_PLUGINHOST_AU 1
#endif

//==============================================================================
// juce_core flags:

#ifndef    JUCE_FORCE_DEBUG
 //#define JUCE_FORCE_DEBUG 1
#endif

#ifndef    JUCE_LOG_ASSERTIONS
 //#define JUCE_LOG_ASSERTIONS 1
#endif

#ifndef    JUCE_CHECK_MEMORY_LEAKS
 #define   JUCE_CHECK_MEMORY_LEAKS 0
#endif

#ifndef    JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
 //#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 1
#endif

#ifndef    JUCE_INCLUDE_ZLIB_CODE
 //#define JUCE_INCLUDE_ZLIB_CODE 1
#endif

#ifndef    JUCE_USE_CURL
 //#define JUCE_USE_CURL 1
#endif

#ifndef    JUCE_CATCH_UNHANDLED_EXCEPTIONS
 //#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
#endif

#ifndef    JUCE_ALLOW_STATIC_NULL_VARIABLES
 //#define JUCE_ALLOW_STATIC_NULL_VARIABLES 1
#endif

//==============================================================================
// juce_events flags:

#ifndef    JUCE_EXECUTE_APP_SUSPEND_ON_IOS_BACKGROUND_TASK
 //#define JUCE_EXECUTE_APP_SUSPEND_ON_IOS_BACKGROUND_TASK 1
#endif

//==============================================================================
// juce_graphics flags:

#ifndef    JUCE_USE_COREIMAGE_LOADER
 //#define JUCE_USE_COREIMAGE_LOADER 1
#endif

#ifndef    JUCE_USE_DIRECTWRITE
 //#define JUCE_USE_DIRECTWRITE 1
#endif

//==============================================================================
// juce_gui_basics flags:

#ifndef    JUCE_ENABLE_REPAINT_DEBUGGING
 //#define JUCE_ENABLE_REPAINT_DEBUGGING 1
#endif

#ifndef    JUCE_USE_XSHM
 //#define JUCE_USE_XSHM 1
#endif

#ifndef    JUCE_USE_XRENDER
 //#define JUCE_USE_XRENDER 1
#endif

#ifndef    JUCE_USE_XCURSOR
 //#define JUCE_USE_XCURSOR 1
#endif

//==============================================================================
// juce_gui_extra flags:

#ifndef    JUCE_WEB_BROWSER
 #define   JUCE_WEB_BROWSER 0
#endif

#ifndef    JUCE_ENABLE_LIVE_CONSTANT_EDITOR
 //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR 1
#endif

//==============================================================================
// juce_video flags:

#ifndef    JUCE_USE_CAMERA
 //#define JUCE_USE_CAMERA 1
#endif
//==============================================================================
#ifndef    JUCE_STANDALONE_APPLICATION
 #if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone)
  #define  JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone
 #else
  #define  JUCE_STANDALONE_APPLICATION 0
 #endif
#endif


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_cryptography/juce_cryptography.mm>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_audio_devices/juce_audio_devices.cpp>


text:
 Important Note!!
 ================

The purpose of this folder is to contain files that are auto-generated by the Projucer,
and ALL files in this folder will be mercilessly DELETED and completely re-written whenever
the Projucer saves your project.

Therefore, it's a bad idea to make any manual changes to the files in here, or to
put any of your own files in here if you don't want to lose them. (Of course you may choose
to add the folder's contents to your version-control system so that you can re-merge your own
modifications after the Projucer has saved its changes).


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_opengl/juce_opengl.cpp>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_gui_extra/juce_gui_extra.cpp>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_gui_basics/juce_gui_basics.cpp>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_gui_extra/juce_gui_extra.mm>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_events/juce_events.mm>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_core/juce_core.cpp>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_audio_processors/juce_audio_processors.mm>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_audio_basics/juce_audio_basics.cpp>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_audio_formats/juce_audio_formats.cpp>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_audio_processors/juce_audio_processors.cpp>


text:
/*

    IMPORTANT! This file is auto-generated each time you save your
    project - if you alter its contents, your changes may be overwritten!

*/

#include "AppConfig.h"
#include <juce_gui_basics/juce_gui_basics.mm>