changeset 0:4606bd505630 tip

first import
author Fiore Martin <f.martin@qmul.ac.uk>
date Sat, 13 Jun 2015 15:08:10 +0100
parents
children
files .hgignore AccessiblePeakMeter-aax.vcxproj AccessiblePeakMeter-aax.vcxproj.filters AccessiblePeakMeter-aax.vcxproj.user AccessiblePeakMeter-vst2.vcxproj AccessiblePeakMeter-vst2.vcxproj.filters AccessiblePeakMeter-vst2.vcxproj.user AccessiblePeakMeter-vst3.vcxproj AccessiblePeakMeter-vst3.vcxproj.filters AccessiblePeakMeter-vst3.vcxproj.user AccessiblePeakMeter.cbp AccessiblePeakMeter.cpp AccessiblePeakMeter.exp AccessiblePeakMeter.h AccessiblePeakMeter.props AccessiblePeakMeter.rc AccessiblePeakMeter.sln AccessiblePeakMeter.xcconfig AccessiblePeakMeter.xcodeproj/oli.pbxuser AccessiblePeakMeter.xcodeproj/project.pbxproj AccessiblePeakMeter_controls.h README.txt app_wrapper/app_dialog.cpp app_wrapper/app_main.cpp app_wrapper/app_main.h app_wrapper/app_resource.h app_wrapper/main.mm resource.h resources/AccessiblePeakMeter-AAX-Info.plist resources/AccessiblePeakMeter-AU-Info.plist resources/AccessiblePeakMeter-IOSAPP-Info.plist resources/AccessiblePeakMeter-OSXAPP-Info.plist resources/AccessiblePeakMeter-Pages.xml resources/AccessiblePeakMeter-RTAS-Info.plist resources/AccessiblePeakMeter-VST2-Info.plist resources/AccessiblePeakMeter-VST3-Info.plist resources/AccessiblePeakMeter-icon57x57.png resources/AccessiblePeakMeter.entitlements resources/AccessiblePeakMeter.icns resources/English.lproj/InfoPlist.strings resources/English.lproj/MainMenu.xib resources/FlipsideView.xib resources/MainView.xib resources/MainWindow.xib resources/img/bg.png resources/img/fader.png resources/img/knob.png resources/img/switch.png stk/include/ADSR.h stk/include/Envelope.h stk/include/Generator.h stk/include/Mutex.h stk/include/RtAudio.h stk/include/RtWvOut.h stk/include/SineWave.h stk/include/Stk.h stk/include/WvOut.h stk/src/ADSR.cpp stk/src/Envelope.cpp stk/src/Mutex.cpp stk/src/RtAudio.cpp stk/src/RtWvOut.cpp stk/src/SineWave.cpp stk/src/Stk.cpp stk/stk-license.txt
diffstat 65 files changed, 26673 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,4 @@
+syntax: glob
+re:^AccessiblePeakMeter\.v12\.suo$
+re:^AccessiblePeakMeter\.sdf$
+re:^build-win/vst2/Win32/Release/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter-aax.vcxproj	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,541 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Tracer|Win32">
+      <Configuration>Tracer</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Tracer|x64">
+      <Configuration>Tracer</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{DC4B5920-933D-4C82-B842-F34431D55A93}</ProjectGuid>
+    <RootNamespace>AccessiblePeakMeter-aax</RootNamespace>
+    <Keyword>ManagedCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">build-win\aax\bin\$(BINARY_NAME).aaxplugin\Contents\$(Platform)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">build-win\aax\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">build-win\aax\bin\$(BINARY_NAME).aaxplugin\Contents\$(Platform)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">build-win\aax\bin\$(BINARY_NAME).aaxplugin\Contents\$(Platform)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">build-win\aax\$(Platform)\$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">build-win\aax\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">build-win\aax\bin\$(BINARY_NAME).aaxplugin\Contents\$(Platform)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">build-win\aax\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">build-win\aax\bin\$(BINARY_NAME).aaxplugin\Contents\$(Platform)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">build-win\aax\bin\$(BINARY_NAME).aaxplugin\Contents\$(Platform)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">build-win\aax\$(Platform)\$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">build-win\aax\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <PreBuildEvent>
+      <Command>DEL /Q /F /S .\build-win\aax\bin\$(BINARY_NAME).aaxplugin\Contents\Win32\
+CALL ..\..\AAX_SDK\Utilities\CreatePackage.bat $(OutDir) ..\..\AAX_SDK\Utilities\PlugIn.ico
+</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+      <Command>
+      </Command>
+      <Outputs>%(Outputs)</Outputs>
+    </CustomBuildStep>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(AAX_INCLUDES);.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>$(AAX_DEFS);$(DEBUG_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>false</MinimalRebuild>
+      <ExceptionHandling>Async</ExceptionHandling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeaderOutputFile>$(IntDir)AccessiblePeakMeter.pch</PrecompiledHeaderOutputFile>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <ForcedIncludeFiles>%(ForcedIncludeFiles)</ForcedIncludeFiles>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>$(AAX_LIBS)</AdditionalDependencies>
+      <OutputFile>$(OutDir)$(BINARY_NAME).aaxplugin</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AssemblyDebug>
+      </AssemblyDebug>
+      <ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(IntDir)$(TargetName).map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+    </Link>
+    <Bscmake>
+      <OutputFile>$(OutDir)$(ProjectName).bsc</OutputFile>
+    </Bscmake>
+    <PostBuildEvent>
+      <Message>Copying AAX plugin folder to $(AAX_PLUGINS_PATH)</Message>
+      <Command>xcopy /E /Y /i ".\build-win\aax\bin\$(BINARY_NAME).aaxplugin" "$(AAX_PLUGINS_PATH)\$(BINARY_NAME).aaxplugin"</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <PreBuildEvent>
+      <Command>DEL /Q /F /S .\build-win\aax\bin\$(BINARY_NAME).aaxplugin\Contents\Win32\
+CALL ..\..\AAX_SDK\Utilities\CreatePackage.bat $(OutDir) ..\..\AAX_SDK\Utilities\PlugIn.ico
+</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+      <Command>
+      </Command>
+      <Outputs>%(Outputs)</Outputs>
+    </CustomBuildStep>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <AdditionalIncludeDirectories>$(AAX_INCLUDES);.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>$(AAX_DEFS);$(RELEASE_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>false</MinimalRebuild>
+      <ExceptionHandling>Async</ExceptionHandling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>
+      </AssemblerListingLocation>
+      <ProgramDataBaseFileName>$(IntDir)vc70.pdb</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <ForcedIncludeFiles>%(ForcedIncludeFiles)</ForcedIncludeFiles>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>$(AAX_LIBS)</AdditionalDependencies>
+      <OutputFile>$(OutDir)$(BINARY_NAME).aaxplugin</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+    </Link>
+    <Bscmake>
+      <OutputFile>$(OutDir)$(ProjectName).bsc</OutputFile>
+    </Bscmake>
+    <PostBuildEvent>
+      <Message>Copying AAX plugin folder to $(AAX_PLUGINS_PATH)</Message>
+      <Command>xcopy /E /Y /i ".\build-win\aax\bin\$(BINARY_NAME).aaxplugin" "$(AAX_PLUGINS_PATH)\$(BINARY_NAME).aaxplugin"</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">
+    <PreBuildEvent>
+      <Command>DEL /Q /F /S .\build-win\aax\bin\$(BINARY_NAME).aaxplugin\Contents\Win32\
+CALL ..\..\AAX_SDK\Utilities\CreatePackage.bat $(OutDir) ..\..\AAX_SDK\Utilities\PlugIn.ico
+</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+      <Command>
+      </Command>
+      <Outputs>%(Outputs)</Outputs>
+    </CustomBuildStep>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <AdditionalIncludeDirectories>$(AAX_INCLUDES);.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>$(AAX_DEFS);$(TRACER_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>false</MinimalRebuild>
+      <ExceptionHandling>Async</ExceptionHandling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>
+      </AssemblerListingLocation>
+      <ProgramDataBaseFileName>$(IntDir)vc70.pdb</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <ForcedIncludeFiles>%(ForcedIncludeFiles)</ForcedIncludeFiles>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>$(AAX_LIBS)</AdditionalDependencies>
+      <OutputFile>$(OutDir)$(BINARY_NAME).aaxplugin</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+    </Link>
+    <Bscmake>
+      <OutputFile>$(OutDir)$(ProjectName).bsc</OutputFile>
+    </Bscmake>
+    <PostBuildEvent>
+      <Message>Copying AAX plugin folder to $(AAX_PLUGINS_PATH)</Message>
+      <Command>xcopy /E /Y /i ".\build-win\aax\bin\$(BINARY_NAME).aaxplugin" "$(AAX_PLUGINS_PATH)\$(BINARY_NAME).aaxplugin"</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <PreBuildEvent>
+      <Command>DEL /Q /F /S .\build-win\aax\bin\$(BINARY_NAME).aaxplugin\Contents\x64\
+      </Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+      <Command>
+      </Command>
+      <Outputs>%(Outputs)</Outputs>
+    </CustomBuildStep>
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(AAX_INCLUDES);.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>$(AAX_DEFS);$(DEBUG_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>false</MinimalRebuild>
+      <ExceptionHandling>Async</ExceptionHandling>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeaderOutputFile>$(IntDir)AccessiblePeakMeter.pch</PrecompiledHeaderOutputFile>
+      <BrowseInformation>true</BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <ForcedIncludeFiles>%(ForcedIncludeFiles)</ForcedIncludeFiles>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>$(AAX_LIBS)</AdditionalDependencies>
+      <OutputFile>$(OutDir)$(BINARY_NAME).aaxplugin</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AssemblyDebug>
+      </AssemblyDebug>
+      <ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(IntDir)$(TargetName).map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <Bscmake>
+      <OutputFile>$(OutDir)$(ProjectName).bsc</OutputFile>
+    </Bscmake>
+    <PostBuildEvent>
+      <Message>Copying AAX plugin folder to $(AAX_PLUGINS_PATH)</Message>
+      <Command>xcopy /E /Y /i ".\build-win\aax\bin\$(BINARY_NAME).aaxplugin" "$(AAX_PLUGINS_PATH)\$(BINARY_NAME).aaxplugin"</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <PreBuildEvent>
+      <Command>DEL /Q /F /S .\build-win\aax\bin\$(BINARY_NAME).aaxplugin\Contents\x64\
+      </Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+      <Command>
+      </Command>
+      <Outputs>%(Outputs)</Outputs>
+    </CustomBuildStep>
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <AdditionalIncludeDirectories>$(AAX_INCLUDES);.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>$(AAX_DEFS);$(RELEASE_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>false</MinimalRebuild>
+      <ExceptionHandling>Async</ExceptionHandling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>
+      </AssemblerListingLocation>
+      <ProgramDataBaseFileName>$(IntDir)vc70.pdb</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <ForcedIncludeFiles>%(ForcedIncludeFiles)</ForcedIncludeFiles>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>$(AAX_LIBS)</AdditionalDependencies>
+      <OutputFile>$(OutDir)$(BINARY_NAME).aaxplugin</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <Bscmake>
+      <OutputFile>$(OutDir)$(ProjectName).bsc</OutputFile>
+    </Bscmake>
+    <PostBuildEvent>
+      <Message>Copying AAX plugin folder to $(AAX_PLUGINS_PATH)</Message>
+      <Command>xcopy /E /Y /i ".\build-win\aax\bin\$(BINARY_NAME).aaxplugin" "$(AAX_PLUGINS_PATH)\$(BINARY_NAME).aaxplugin"</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">
+    <PreBuildEvent>
+      <Command>DEL /Q /F /S .\build-win\aax\bin\$(BINARY_NAME).aaxplugin\Contents\x64\
+      </Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+      <Command>
+      </Command>
+      <Outputs>%(Outputs)</Outputs>
+    </CustomBuildStep>
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <AdditionalIncludeDirectories>$(AAX_INCLUDES);.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>$(AAX_DEFS);$(TRACER_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>false</MinimalRebuild>
+      <ExceptionHandling>Async</ExceptionHandling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>
+      </AssemblerListingLocation>
+      <ProgramDataBaseFileName>$(IntDir)vc70.pdb</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <CompileAs>Default</CompileAs>
+      <ForcedIncludeFiles>%(ForcedIncludeFiles)</ForcedIncludeFiles>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>$(AAX_LIBS)</AdditionalDependencies>
+      <OutputFile>$(OutDir)$(BINARY_NAME).aaxplugin</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <Bscmake>
+      <OutputFile>$(OutDir)$(ProjectName).bsc</OutputFile>
+    </Bscmake>
+    <PostBuildEvent>
+      <Message>Copying AAX plugin folder to $(AAX_PLUGINS_PATH)</Message>
+      <Command>xcopy /E /Y /i ".\build-win\aax\bin\$(BINARY_NAME).aaxplugin" "$(AAX_PLUGINS_PATH)\$(BINARY_NAME).aaxplugin"</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\AAX_SDK\Interfaces\AAX_Exports.cpp">
+      <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(Filename)1.obj</ObjectFileName>
+      <XMLDocumentationFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(Filename)1.xdc</XMLDocumentationFileName>
+      <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename)1.obj</ObjectFileName>
+      <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">$(IntDir)%(Filename)1.obj</ObjectFileName>
+      <XMLDocumentationFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename)1.xdc</XMLDocumentationFileName>
+      <XMLDocumentationFileName Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">$(IntDir)%(Filename)1.xdc</XMLDocumentationFileName>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\Hosts.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\IBitmapMonoText.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\IControl.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\IGraphics.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\IGraphicsWin.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\IParam.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\IPlugBase.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\IPlugStructs.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\IPopupMenu.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\Log.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\AAX\AAX_CIPlugParameters.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\IPlugAAX.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\AAX\IPlugAAX_Describe.cpp" />
+    <ClCompile Include="AccessiblePeakMeter.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <CustomBuildStep Include="..\..\AAX_SDK\Libs\Release\AAXLibrary.lib">
+      <FileType>Document</FileType>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">true</ExcludedFromBuild>
+    </CustomBuildStep>
+    <CustomBuildStep Include="..\..\AAX_SDK\Libs\Debug\AAXLibrary_D.lib">
+      <FileType>Document</FileType>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">true</ExcludedFromBuild>
+    </CustomBuildStep>
+    <CustomBuildStep Include="..\..\AAX_SDK\Libs\Release\AAXLibrary_x64.lib">
+      <FileType>Document</FileType>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">true</ExcludedFromBuild>
+    </CustomBuildStep>
+    <CustomBuildStep Include="..\..\AAX_SDK\Libs\Debug\AAXLibrary_x64_D.lib">
+      <FileType>Document</FileType>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">true</ExcludedFromBuild>
+    </CustomBuildStep>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\WDL\IPlug\Containers.h" />
+    <ClInclude Include="..\..\WDL\IPlug\Hosts.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IBitmapMonoText.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IControl.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IGraphics.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IGraphicsWin.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IKeyboardControl.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IMidiQueue.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IParam.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IPlug_include_in_plug_hdr.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IPlug_include_in_plug_src.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IPlugBase.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IPlugOSDetect.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IPlugStructs.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IPopupMenu.h" />
+    <ClInclude Include="..\..\WDL\IPlug\Log.h" />
+    <ClInclude Include="..\..\WDL\IPlug\AAX\AAX_CIPlugParameters.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IPlugAAX.h" />
+    <ClInclude Include="AccessiblePeakMeter.h" />
+    <ClInclude Include="resource.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="AccessiblePeakMeter.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <Library Include="..\..\AAX_SDK\Libs\Debug\AAXLibrary_D.lib">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">true</ExcludedFromBuild>
+    </Library>
+    <Library Include="..\..\AAX_SDK\Libs\Debug\AAXLibrary_x64_D.lib">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">true</ExcludedFromBuild>
+    </Library>
+    <Library Include="..\..\AAX_SDK\Libs\Release\AAXLibrary.lib">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">true</ExcludedFromBuild>
+    </Library>
+    <Library Include="..\..\AAX_SDK\Libs\Release\AAXLibrary_x64.lib">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">true</ExcludedFromBuild>
+    </Library>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter-aax.vcxproj.filters	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="IPlug">
+      <UniqueIdentifier>{ed0eb9dd-b586-4a3f-98af-ebd9c084fff2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="IPlug\AAX">
+      <UniqueIdentifier>{a484aa50-ad02-4746-957e-117c8bb5c192}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Libs">
+      <UniqueIdentifier>{57d1624e-a679-47da-bd3e-9609f02fdd7b}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\WDL\IPlug\Hosts.cpp">
+      <Filter>IPlug</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\IBitmapMonoText.cpp">
+      <Filter>IPlug</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\IControl.cpp">
+      <Filter>IPlug</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\IGraphics.cpp">
+      <Filter>IPlug</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\IGraphicsWin.cpp">
+      <Filter>IPlug</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\IParam.cpp">
+      <Filter>IPlug</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\IPlugBase.cpp">
+      <Filter>IPlug</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\IPlugStructs.cpp">
+      <Filter>IPlug</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\IPopupMenu.cpp">
+      <Filter>IPlug</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\Log.cpp">
+      <Filter>IPlug</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\AAX\AAX_CIPlugParameters.cpp">
+      <Filter>IPlug\AAX</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\IPlugAAX.cpp">
+      <Filter>IPlug\AAX</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\AAX\IPlugAAX_Describe.cpp">
+      <Filter>IPlug\AAX</Filter>
+    </ClCompile>
+    <ClCompile Include="AccessiblePeakMeter.cpp" />
+    <ClCompile Include="..\..\AAX_SDK\Interfaces\AAX_Exports.cpp">
+      <Filter>Libs</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\WDL\IPlug\Containers.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\Hosts.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IBitmapMonoText.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IControl.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IGraphics.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IGraphicsWin.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IKeyboardControl.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IMidiQueue.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IParam.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IPlug_include_in_plug_hdr.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IPlug_include_in_plug_src.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IPlugBase.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IPlugOSDetect.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IPlugStructs.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IPopupMenu.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\Log.h">
+      <Filter>IPlug</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\AAX\AAX_CIPlugParameters.h">
+      <Filter>IPlug\AAX</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IPlugAAX.h">
+      <Filter>IPlug\AAX</Filter>
+    </ClInclude>
+    <ClInclude Include="AccessiblePeakMeter.h" />
+    <ClInclude Include="resource.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="AccessiblePeakMeter.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <Library Include="..\..\AAX_SDK\Libs\Debug\AAXLibrary_x64_D.lib">
+      <Filter>Libs</Filter>
+    </Library>
+    <Library Include="..\..\AAX_SDK\Libs\Release\AAXLibrary.lib">
+      <Filter>Libs</Filter>
+    </Library>
+    <Library Include="..\..\AAX_SDK\Libs\Debug\AAXLibrary_D.lib">
+      <Filter>Libs</Filter>
+    </Library>
+    <Library Include="..\..\AAX_SDK\Libs\Release\AAXLibrary_x64.lib">
+      <Filter>Libs</Filter>
+    </Library>
+  </ItemGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter-aax.vcxproj.user	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter-vst2.vcxproj	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Tracer|Win32">
+      <Configuration>Tracer</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Tracer|x64">
+      <Configuration>Tracer</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{2EB4846A-93E0-43A0-821E-12237105168F}</ProjectGuid>
+    <RootNamespace>AccessiblePeakMeter</RootNamespace>
+    <ProjectName>AccessiblePeakMeter-vst2</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>$(VSTPLUGINS)</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>$(VSTPLUGINS)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <IntDir>build-win\vst2\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>
+    </LinkIncremental>
+    <TargetName>$(BINARY_NAME)2S</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <IntDir>build-win\vst2\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental />
+    <TargetName>$(BINARY_NAME)2S64</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>$(VSTPLUGINS)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>$(VSTPLUGINS)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <IntDir>build-win\vst2\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>$(BINARY_NAME)2S</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <IntDir>build-win\vst2\$(Platform)\$(Configuration)\</IntDir>
+    <TargetName>$(BINARY_NAME)2S64</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">
+    <OutDir>build-win\vst2\$(Platform)\bin\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">
+    <OutDir>build-win\vst2\$(Platform)\bin\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">
+    <IntDir>build-win\vst2\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">
+    <IntDir>build-win\vst2\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>$(VST_DEFS);$(DEBUG_DEFS);__OS_WINDOWS__;__WINDOWS_WASAPI__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>$(VST_DEFS);$(DEBUG_DEFS);__OS_WINDOWS__;__WINDOWS_WASAPI__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <AdditionalLibraryDirectories>$(x64_LIB_PATHS);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>$(VST_DEFS);$(RELEASE_DEFS);__OS_WINDOWS__;__WINDOWS_WASAPI__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>$(VST_DEFS);$(RELEASE_DEFS);__OS_WINDOWS__;__WINDOWS_WASAPI__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <SubSystem>Windows</SubSystem>
+      <AdditionalLibraryDirectories>$(x64_LIB_PATHS);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>$(VST_DEFS);$(TRACER_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <SubSystem>Windows</SubSystem>
+      <AdditionalLibraryDirectories>$(WDL_PATH)\lice\build-win\$(Platform)\Release\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>$(VST_DEFS);$(TRACER_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <SubSystem>Windows</SubSystem>
+      <AdditionalLibraryDirectories>$(x64_LIB_PATHS);$(WDL_PATH)\lice\build-win\$(Platform)\Release\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\WDL\IPlug\IPlugVST.h" />
+    <ClInclude Include="AccessiblePeakMeter.h" />
+    <ClInclude Include="resource.h" />
+    <ClInclude Include="stk\include\ADSR.h" />
+    <ClInclude Include="stk\include\Envelope.h" />
+    <ClInclude Include="stk\include\Generator.h" />
+    <ClInclude Include="stk\include\Mutex.h" />
+    <ClInclude Include="stk\include\RtAudio.h" />
+    <ClInclude Include="stk\include\RtWvOut.h" />
+    <ClInclude Include="stk\include\SineWave.h" />
+    <ClInclude Include="stk\include\Stk.h" />
+    <ClInclude Include="stk\include\WvOut.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\WDL\IPlug\IPlugVST.cpp" />
+    <ClCompile Include="AccessiblePeakMeter.cpp" />
+    <ClCompile Include="stk\src\ADSR.cpp" />
+    <ClCompile Include="stk\src\Envelope.cpp" />
+    <ClCompile Include="stk\src\Mutex.cpp" />
+    <ClCompile Include="stk\src\RtAudio.cpp" />
+    <ClCompile Include="stk\src\RtWvOut.cpp" />
+    <ClCompile Include="stk\src\SineWave.cpp" />
+    <ClCompile Include="stk\src\Stk.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="AccessiblePeakMeter.rc" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter-vst2.vcxproj.filters	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="AccessiblePeakMeter.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\IPlugVST.cpp">
+      <Filter>vst2</Filter>
+    </ClCompile>
+    <ClCompile Include="stk\src\SineWave.cpp" />
+    <ClCompile Include="stk\src\Stk.cpp" />
+    <ClCompile Include="stk\src\Envelope.cpp" />
+    <ClCompile Include="stk\src\ADSR.cpp" />
+    <ClCompile Include="stk\src\Mutex.cpp" />
+    <ClCompile Include="stk\src\RtAudio.cpp" />
+    <ClCompile Include="stk\src\RtWvOut.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="AccessiblePeakMeter.h" />
+    <ClInclude Include="resource.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IPlugVST.h">
+      <Filter>vst2</Filter>
+    </ClInclude>
+    <ClInclude Include="stk\include\Generator.h" />
+    <ClInclude Include="stk\include\SineWave.h" />
+    <ClInclude Include="stk\include\Stk.h" />
+    <ClInclude Include="stk\include\Envelope.h" />
+    <ClInclude Include="stk\include\ADSR.h" />
+    <ClInclude Include="stk\include\Mutex.h" />
+    <ClInclude Include="stk\include\RtAudio.h" />
+    <ClInclude Include="stk\include\RtWvOut.h" />
+    <ClInclude Include="stk\include\WvOut.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="AccessiblePeakMeter.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <Filter Include="vst2">
+      <UniqueIdentifier>{ea16de74-9d15-4c60-ba09-d0924088d3e5}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter-vst2.vcxproj.user	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LocalDebuggerCommandArguments>$(TargetPath) /noload /nosave  /noexc /noft</LocalDebuggerCommandArguments>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerCommand>$(VST2_32_HOST_PATH)</LocalDebuggerCommand>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LocalDebuggerCommandArguments>$(TargetPath) /noload /nosave</LocalDebuggerCommandArguments>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
+    <LocalDebuggerCommand>$(VST2_32_HOST_PATH)</LocalDebuggerCommand>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">
+    <LocalDebuggerCommandArguments>$(TargetPath) /noload /nosave</LocalDebuggerCommandArguments>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
+    <LocalDebuggerCommand>$(VST2_32_HOST_PATH)</LocalDebuggerCommand>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerCommandArguments>$(TargetPath) /noload /nosave</LocalDebuggerCommandArguments>
+    <LocalDebuggerCommand>$(VST2_64_HOST_PATH)</LocalDebuggerCommand>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerCommandArguments>$(TargetPath) /noload /nosave</LocalDebuggerCommandArguments>
+    <LocalDebuggerCommand>$(VST2_64_HOST_PATH)</LocalDebuggerCommand>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">
+    <LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerCommandArguments>$(TargetPath) /noload /nosave</LocalDebuggerCommandArguments>
+    <LocalDebuggerCommand>$(VST2_64_HOST_PATH)</LocalDebuggerCommand>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter-vst3.vcxproj	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,350 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Tracer|Win32">
+      <Configuration>Tracer</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Tracer|x64">
+      <Configuration>Tracer</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{079FC65A-F0E5-4E97-B318-A16D1D0B89DF}</ProjectGuid>
+    <RootNamespace>AccessiblePeakMeter</RootNamespace>
+    <ProjectName>AccessiblePeakMeter-vst3</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="AccessiblePeakMeter.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>build-win\vst3\$(Platform)\bin\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>build-win\vst3\$(Platform)\bin\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <IntDir>build-win\vst3\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental>
+    </LinkIncremental>
+    <TargetExt>.vst3</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <IntDir>build-win\vst3\$(Platform)\$(Configuration)\</IntDir>
+    <LinkIncremental />
+    <TargetExt>.vst3</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>build-win\vst3\$(Platform)\bin\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>build-win\vst3\$(Platform)\bin\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <IntDir>build-win\vst3\$(Platform)\$(Configuration)\</IntDir>
+    <TargetExt>.vst3</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <IntDir>build-win\vst3\$(Platform)\$(Configuration)\</IntDir>
+    <TargetExt>.vst3</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">
+    <OutDir>build-win\vst3\$(Platform)\bin\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">
+    <OutDir>build-win\vst3\$(Platform)\bin\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">
+    <IntDir>build-win\vst3\$(Platform)\$(Configuration)\</IntDir>
+    <TargetExt>.vst3</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">
+    <IntDir>build-win\vst3\$(Platform)\$(Configuration)\</IntDir>
+    <TargetExt>.vst3</TargetExt>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>$(VST3_DEFS);$(DEBUG_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <AdditionalIncludeDirectories>$(VST3_INCLUDES);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <AdditionalDependencies>base.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\VST3_SDK\base\win\$(Platform)\$(Configuration)\;$(WDL_PATH)\IPlug\build-win\$(Platform)\$(Configuration)\;$(WDL_PATH)\lice\build-win\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <ModuleDefinitionFile>$(WDL_PATH)\IPlug\IPlugVST3.def</ModuleDefinitionFile>
+    </Link>
+    <PostBuildEvent>
+      <Command>echo Post-Build: copy 32bit binary to 32bit VST3 Plugins folder ... ...
+copy /y "$(TargetPath)" "$(VST3_32_PATH)\AccessiblePeakMeter.vst3"</Command>
+      <Message>Copy VST3 Binary to VST3 Plugins folder</Message>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>$(VST3_DEFS);$(DEBUG_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <AdditionalIncludeDirectories>$(VST3_INCLUDES);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <AdditionalLibraryDirectories>..\..\VST3_SDK\base\win\$(Platform)\$(Configuration)\;$(x64_LIB_PATHS);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>base.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>$(WDL_PATH)\IPlug\IPlugVST3.def</ModuleDefinitionFile>
+    </Link>
+    <PostBuildEvent>
+      <Command>echo Post-Build: copy 64bit binary to 64bit VST3 Plugins folder ...
+if exist "%programfiles(x86)%" (copy /y "$(TargetPath)" "$(VST3_64_PATH)\AccessiblePeakMeter.vst3") else (echo Not copying 64bit binary - 32bit OS detected)</Command>
+      <Message>Copy VST3 Binary to VST3 Plugins folder</Message>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>$(VST3_DEFS);$(RELEASE_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <AdditionalIncludeDirectories>$(VST3_INCLUDES);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <SubSystem>Windows</SubSystem>
+      <AdditionalDependencies>base.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\VST3_SDK\base\win\$(Platform)\$(Configuration)\;$(WDL_PATH)\IPlug\build-win\$(Platform)\$(Configuration)\;$(WDL_PATH)\lice\build-win\$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <ModuleDefinitionFile>$(WDL_PATH)\IPlug\IPlugVST3.def</ModuleDefinitionFile>
+    </Link>
+    <PostBuildEvent>
+      <Command>echo Post-Build: copy 32bit binary to 32bit VST3 Plugins folder ... ...
+copy /y "$(TargetPath)" "$(VST3_32_PATH)\AccessiblePeakMeter.vst3"</Command>
+      <Message>Copy VST3 Binary to VST3 Plugins folder</Message>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>$(VST3_DEFS);$(RELEASE_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <AdditionalIncludeDirectories>$(VST3_INCLUDES);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <SubSystem>Windows</SubSystem>
+      <AdditionalLibraryDirectories>..\..\VST3_SDK\base\win\$(Platform)\$(Configuration)\;$(x64_LIB_PATHS);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>base.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>$(WDL_PATH)\IPlug\IPlugVST3.def</ModuleDefinitionFile>
+    </Link>
+    <PostBuildEvent>
+      <Command>echo Post-Build: copy 64bit binary to 64bit VST3 Plugins folder ...
+if exist "%programfiles(x86)%" (copy /y "$(TargetPath)" "$(VST3_64_PATH)\AccessiblePeakMeter.vst3") else (echo Not copying 64bit binary - 32bit OS detected)</Command>
+      <Message>Copy VST3 Binary to VST3 Plugins folder</Message>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>$(VST3_DEFS);$(TRACER_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <AdditionalIncludeDirectories>$(VST3_INCLUDES);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <SubSystem>Windows</SubSystem>
+      <AdditionalLibraryDirectories>$(WDL_PATH)\lice\build-win\$(Platform)\Release\;..\..\VST3_SDK\base\win\$(Platform)\Release\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>base.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>$(WDL_PATH)\IPlug\IPlugVST3.def</ModuleDefinitionFile>
+    </Link>
+    <PostBuildEvent>
+      <Command>echo Post-Build: copy 32bit binary to 32bit VST3 Plugins folder ... ...
+copy /y "$(TargetPath)" "$(VST3_32_PATH)\AccessiblePeakMeter.vst3"</Command>
+      <Message>Copy VST3 Binary to VST3 Plugins folder</Message>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>$(VST3_DEFS);$(TRACER_DEFS);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <AdditionalIncludeDirectories>$(VST3_INCLUDES);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <SubSystem>Windows</SubSystem>
+      <AdditionalLibraryDirectories>$(x64_LIB_PATHS);$(WDL_PATH)\lice\build-win\$(Platform)\Release\;..\..\VST3_SDK\base\win\$(Platform)\Release\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>base.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>$(WDL_PATH)\IPlug\IPlugVST3.def</ModuleDefinitionFile>
+    </Link>
+    <PostBuildEvent>
+      <Command>echo Post-Build: copy 64bit binary to 64bit VST3 Plugins folder ...
+if exist "%programfiles(x86)%" (copy /y "$(TargetPath)" "$(VST3_64_PATH)\AccessiblePeakMeter.vst3") else (echo Not copying 64bit binary - 32bit OS detected)</Command>
+      <Message>Copy VST3 Binary to VST3 Plugins folder</Message>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\falignpop.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\falignpush.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\fplatform.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\ftypes.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\funknown.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\ipluginbase.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\keycodes.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\ustring.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\gui\iplugview.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstattributes.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstaudioprocessor.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstcomponent.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivsteditcontroller.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstevents.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivsthostapplication.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstmessage.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstmidicontrollers.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstparameterchanges.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstprocesscontext.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstunits.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\vstpresetkeys.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\vsttypes.h" />
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\common\pluginview.h" />
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\main\pluginfactoryvst3.h" />
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vstaudioeffect.h" />
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vstbus.h" />
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vstcomponent.h" />
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vstcomponentbase.h" />
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vsteditcontroller.h" />
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vstparameters.h" />
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vstsinglecomponenteffect.h" />
+    <ClInclude Include="..\..\WDL\IPlug\IPlugVST3.h" />
+    <ClInclude Include="AccessiblePeakMeter.h" />
+    <ClInclude Include="resource.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\VST3_SDK\pluginterfaces\base\funknown.cpp" />
+    <ClCompile Include="..\..\VST3_SDK\pluginterfaces\base\ustring.cpp" />
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\common\pluginview.cpp" />
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\main\dllmain.cpp" />
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\main\pluginfactoryvst3.cpp" />
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstaudioeffect.cpp" />
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstbus.cpp" />
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstcomponent.cpp" />
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstcomponentbase.cpp" />
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstinitiids.cpp" />
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstparameters.cpp" />
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstsinglecomponenteffect.cpp" />
+    <ClCompile Include="..\..\WDL\IPlug\IPlugVST3.cpp" />
+    <ClCompile Include="AccessiblePeakMeter.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="AccessiblePeakMeter.rc" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter-vst3.vcxproj.filters	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="AccessiblePeakMeter.cpp" />
+    <ClCompile Include="..\..\VST3_SDK\pluginterfaces\base\funknown.cpp">
+      <Filter>vst3\VST3SDK\pluginterfaces\base</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\VST3_SDK\pluginterfaces\base\ustring.cpp">
+      <Filter>vst3\VST3SDK\pluginterfaces\base</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\common\pluginview.cpp">
+      <Filter>vst3\VST3SDK\public.sdk\common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstaudioeffect.cpp">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstbus.cpp">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstcomponent.cpp">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstcomponentbase.cpp">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstinitiids.cpp">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstparameters.cpp">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\main\dllmain.cpp">
+      <Filter>vst3\VST3SDK\public.sdk\main</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\main\pluginfactoryvst3.cpp">
+      <Filter>vst3\VST3SDK\public.sdk\main</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\VST3_SDK\public.sdk\source\vst\vstsinglecomponenteffect.cpp">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\WDL\IPlug\IPlugVST3.cpp">
+      <Filter>vst3</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="AccessiblePeakMeter.h" />
+    <ClInclude Include="resource.h" />
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\falignpop.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\base</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\falignpush.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\base</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\fplatform.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\base</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\ftypes.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\base</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\funknown.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\base</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\ipluginbase.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\base</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\keycodes.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\base</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\base\ustring.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\base</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstattributes.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstaudioprocessor.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstcomponent.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivsteditcontroller.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstevents.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivsthostapplication.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstmessage.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstmidicontrollers.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstparameterchanges.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstprocesscontext.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\ivstunits.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\vstpresetkeys.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\vst\vsttypes.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\pluginterfaces\gui\iplugview.h">
+      <Filter>vst3\VST3SDK\pluginterfaces\gui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\common\pluginview.h">
+      <Filter>vst3\VST3SDK\public.sdk\common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vstaudioeffect.h">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vstbus.h">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vstcomponent.h">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vstcomponentbase.h">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vsteditcontroller.h">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vstparameters.h">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\main\pluginfactoryvst3.h">
+      <Filter>vst3\VST3SDK\public.sdk\main</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\VST3_SDK\public.sdk\source\vst\vstsinglecomponenteffect.h">
+      <Filter>vst3\VST3SDK\public.sdk\vst</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\WDL\IPlug\IPlugVST3.h">
+      <Filter>vst3</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <Filter Include="vst3">
+      <UniqueIdentifier>{0028f8fa-40ce-4098-b1d7-1930d1a7774b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="vst3\VST3SDK">
+      <UniqueIdentifier>{d33dc1fa-0b31-40b9-a240-b065db740979}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="vst3\VST3SDK\pluginterfaces">
+      <UniqueIdentifier>{1da1c979-a505-4558-b877-1a2da0e4e758}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="vst3\VST3SDK\pluginterfaces\base">
+      <UniqueIdentifier>{cf0c95d2-7b5a-4afa-8a3e-546800d9b337}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="vst3\VST3SDK\pluginterfaces\vst">
+      <UniqueIdentifier>{babb4a18-d1d6-467e-af1c-fb852400f591}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="vst3\VST3SDK\pluginterfaces\gui">
+      <UniqueIdentifier>{a0598a21-18c6-4da8-98a8-bebbf0f37b34}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="vst3\VST3SDK\public.sdk">
+      <UniqueIdentifier>{bc78847c-a41c-4ad7-8a8e-2ea825bc2f8e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="vst3\VST3SDK\public.sdk\common">
+      <UniqueIdentifier>{23863805-5085-4669-8675-167aba1f0fc9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="vst3\VST3SDK\public.sdk\vst">
+      <UniqueIdentifier>{00ff2592-e5ef-4ab1-8b06-c42242d80c52}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="vst3\VST3SDK\public.sdk\main">
+      <UniqueIdentifier>{ec7b025c-4ef1-4403-956b-b3673b4715b8}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="AccessiblePeakMeter.rc" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter-vst3.vcxproj.user	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LocalDebuggerCommand>$(VST3_32_HOST_PATH)</LocalDebuggerCommand>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerCommandArguments>$(TargetPath)</LocalDebuggerCommandArguments>
+    <LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LocalDebuggerCommand>$(VST3_32_HOST_PATH)</LocalDebuggerCommand>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerCommandArguments>$(TargetPath)</LocalDebuggerCommandArguments>
+    <LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|Win32'">
+    <LocalDebuggerCommand>$(VST3_32_HOST_PATH)</LocalDebuggerCommand>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerCommandArguments>$(TargetPath)</LocalDebuggerCommandArguments>
+    <LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LocalDebuggerCommandArguments>$(TargetPath)</LocalDebuggerCommandArguments>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerCommand>$(VST3_64_HOST_PATH)</LocalDebuggerCommand>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LocalDebuggerCommandArguments>$(TargetPath)</LocalDebuggerCommandArguments>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">
+    <LocalDebuggerCommandArguments>$(TargetPath)</LocalDebuggerCommandArguments>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Tracer|x64'">
+    <LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter.cbp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+	<FileVersion major="1" minor="6" />
+	<Project>
+		<Option title="AccessiblePeakMeter" />
+		<Option pch_mode="2" />
+		<Option compiler="gcc" />
+		<Build>
+			<Target title="Debug Win32">
+				<Option output="build-win-cb\AccessiblePeakMeter" prefix_auto="1" extension_auto="1" />
+				<Option working_dir="build-win-cb\" />
+				<Option object_output="build-win-cb\Debug\" />
+				<Option type="3" />
+				<Option compiler="gcc" />
+				<Option parameters="AccessiblePeakMeter.dll" />
+				<Option host_application="C:\Program Files\vsthost\vsthost.exe" />
+				<Compiler>
+					<Add option="-g" />
+					<Add option="-DVST_API" />
+					<Add option="-DWIN32" />
+					<Add option="-D_WIN32_WINNT=0x0501" />
+					<Add option="-DWINVER=0x0501" />
+					<Add option="-D_CRT_SECURE_NO_DEPRECATE" />
+					<Add option="-D_DEBUG" />
+					<Add option="-DPNG_NO_ASSEMBLER_CODE" />
+					<Add option="-DPNG_LIBPNG_SPECIALBUILD" />
+					<Add option="-DDLL_BUILD" />
+				</Compiler>
+			</Target>
+			<Target title="Release Win32">
+				<Option output="build-win-cb\AccessiblePeakMeter" prefix_auto="1" extension_auto="1" />
+				<Option working_dir="build-win-cb\" />
+				<Option object_output="build-win-cb\Release" />
+				<Option type="3" />
+				<Option compiler="gcc" />
+				<Option parameters="AccessiblePeakMeter.dll" />
+				<Option host_application="C:\Program Files\vsthost\vsthost.exe" />
+				<Compiler>
+					<Add option="-O2" />
+					<Add option="-msse2" />
+					<Add option="-ffast-math" />
+					<Add option="-DVST_API" />
+					<Add option="-DWIN32" />
+					<Add option="-D_WIN32_WINNT=0x0501" />
+					<Add option="-DWINVER=0x0501" />
+					<Add option="-D_CRT_SECURE_NO_DEPRECATE" />
+					<Add option="-DPNG_NO_ASSEMBLER_CODE" />
+					<Add option="-DPNG_LIBPNG_SPECIALBUILD" />
+					<Add option="-DDLL_BUILD" />
+					<Add option="-DNDEBUG" />
+				</Compiler>
+			</Target>
+			<Target title="Tracer Win32">
+				<Option output="build-win-cb\AccessiblePeakMeter" prefix_auto="1" extension_auto="1" />
+				<Option working_dir="build-win-cb\" />
+				<Option object_output="build-win-cb\Tracer" />
+				<Option type="3" />
+				<Option compiler="gcc" />
+				<Option parameters="AccessiblePeakMeter.dll" />
+				<Option host_application="C:\Program Files\vsthost\vsthost.exe" />
+				<Compiler>
+					<Add option="-DTRACER_BUILD" />
+					<Add option="-DVST_API" />
+					<Add option="-DWIN32" />
+					<Add option="-D_WIN32_WINNT=0x0501" />
+					<Add option="-DWINVER=0x0501" />
+					<Add option="-D_CRT_SECURE_NO_DEPRECATE" />
+				</Compiler>
+			</Target>
+		</Build>
+		<Compiler>
+			<Add option="-Wno-write-strings" />
+			<Add option="-DVST_FORCE_DEPRECATED" />
+			<Add directory="..\..\WDL\IPlug" />
+			<Add directory="." />
+			<Add directory="..\..\VST_SDK\" />
+			<Add directory="..\..\WDL\zlib" />
+			<Add directory="..\..\WDL\lice" />
+			<Add directory="..\..\WDL\libpng" />
+		</Compiler>
+		<ResourceCompiler>
+			<Add directory=".\" />
+		</ResourceCompiler>
+		<Linker>
+			<Add library="libkernel32" />
+			<Add library="libwininet" />
+			<Add library="libuser32" />
+			<Add library="libgdi32" />
+			<Add library="libwinspool" />
+			<Add library="libcomdlg32" />
+			<Add library="libadvapi32" />
+			<Add library="libshell32" />
+			<Add library="libole32" />
+			<Add library="libuuid" />
+			<Add library="libodbc32" />
+			<Add library="libodbccp32" />
+			<Add library="liboleaut32" />
+		</Linker>
+		<Unit filename="AccessiblePeakMeter.cpp" />
+		<Unit filename="AccessiblePeakMeter.h" />
+		<Unit filename="AccessiblePeakMeter.rc">
+			<Option compilerVar="WINDRES" />
+		</Unit>
+		<Unit filename="resource.h" />
+		<Unit filename="..\..\WDL\IPlug\Containers.h" />
+		<Unit filename="..\..\WDL\IPlug\Hosts.cpp" />
+		<Unit filename="..\..\WDL\IPlug\Hosts.h" />
+		<Unit filename="..\..\WDL\IPlug\IControl.cpp" />
+		<Unit filename="..\..\WDL\IPlug\IControl.h" />
+		<Unit filename="..\..\WDL\IPlug\IGraphics.cpp" />
+		<Unit filename="..\..\WDL\IPlug\IGraphics.h" />
+		<Unit filename="..\..\WDL\IPlug\IGraphicsCarbon.h" />
+		<Unit filename="..\..\WDL\IPlug\IGraphicsCocoa.h" />
+		<Unit filename="..\..\WDL\IPlug\IGraphicsCocoa.mm" />
+		<Unit filename="..\..\WDL\IPlug\IGraphicsLice.h" />
+		<Unit filename="..\..\WDL\IPlug\IGraphicsMac.h" />
+		<Unit filename="..\..\WDL\IPlug\IGraphicsMac.mm" />
+		<Unit filename="..\..\WDL\IPlug\IGraphicsWin.cpp" />
+		<Unit filename="..\..\WDL\IPlug\IGraphicsWin.h" />
+		<Unit filename="..\..\WDL\IPlug\IParam.cpp" />
+		<Unit filename="..\..\WDL\IPlug\IParam.h" />
+		<Unit filename="..\..\WDL\IPlug\IPlugBase.cpp" />
+		<Unit filename="..\..\WDL\IPlug\IPlugBase.h" />
+		<Unit filename="..\..\WDL\IPlug\IPlugOSDetect.h" />
+		<Unit filename="..\..\WDL\IPlug\IPlugStructs.cpp" />
+		<Unit filename="..\..\WDL\IPlug\IPlugStructs.h" />
+		<Unit filename="..\..\WDL\IPlug\IPlugVST.cpp" />
+		<Unit filename="..\..\WDL\IPlug\IPlugVST.h" />
+		<Unit filename="..\..\WDL\IPlug\IPlug_Prefix.pch" />
+		<Unit filename="..\..\WDL\IPlug\IPlug_include_in_plug_hdr.h" />
+		<Unit filename="..\..\WDL\IPlug\IPlug_include_in_plug_src.h" />
+		<Unit filename="..\..\WDL\IPlug\IPopupMenu.cpp" />
+		<Unit filename="..\..\WDL\IPlug\IPopupMenu.h" />
+		<Unit filename="..\..\WDL\IPlug\Log.cpp" />
+		<Unit filename="..\..\WDL\IPlug\Log.h" />
+		<Unit filename="..\..\WDL\IPlug\VSTHosts.h" />
+		<Unit filename="..\..\WDL\libpng\png.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\png.h" />
+		<Unit filename="..\..\WDL\libpng\pngconf.h" />
+		<Unit filename="..\..\WDL\libpng\pngerror.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\pngget.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\pngmem.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\pngpread.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\pngread.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\pngrio.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\pngrtran.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\pngrutil.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\pngset.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\pngtrans.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\pngwio.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\pngwrite.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\pngwtran.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\libpng\pngwutil.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\lice\lice.cpp" />
+		<Unit filename="..\..\WDL\lice\lice.h" />
+		<Unit filename="..\..\WDL\lice\lice_arc.cpp" />
+		<Unit filename="..\..\WDL\lice\lice_bezier.h" />
+		<Unit filename="..\..\WDL\lice\lice_colorspace.cpp" />
+		<Unit filename="..\..\WDL\lice\lice_combine.h" />
+		<Unit filename="..\..\WDL\lice\lice_extended.h" />
+		<Unit filename="..\..\WDL\lice\lice_image.cpp" />
+		<Unit filename="..\..\WDL\lice\lice_line.cpp" />
+		<Unit filename="..\..\WDL\lice\lice_palette.cpp" />
+		<Unit filename="..\..\WDL\lice\lice_png.cpp" />
+		<Unit filename="..\..\WDL\lice\lice_texgen.cpp" />
+		<Unit filename="..\..\WDL\lice\lice_text.cpp" />
+		<Unit filename="..\..\WDL\lice\lice_text.h" />
+		<Unit filename="..\..\WDL\lice\lice_textnew.cpp" />
+		<Unit filename="..\..\WDL\zlib\adler32.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\zlib\compress.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\zlib\crc32.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\zlib\crc32.h" />
+		<Unit filename="..\..\WDL\zlib\deflate.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\zlib\deflate.h" />
+		<Unit filename="..\..\WDL\zlib\infback.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\zlib\inffast.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\zlib\inffast.h" />
+		<Unit filename="..\..\WDL\zlib\inffixed.h" />
+		<Unit filename="..\..\WDL\zlib\inflate.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\zlib\inflate.h" />
+		<Unit filename="..\..\WDL\zlib\inftrees.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\zlib\inftrees.h" />
+		<Unit filename="..\..\WDL\zlib\ioapi.h" />
+		<Unit filename="..\..\WDL\zlib\trees.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\zlib\trees.h" />
+		<Unit filename="..\..\WDL\zlib\uncompr.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\zlib\unzip.h" />
+		<Unit filename="..\..\WDL\zlib\zconf.h" />
+		<Unit filename="..\..\WDL\zlib\zconf.in.h" />
+		<Unit filename="..\..\WDL\zlib\zlib.h" />
+		<Unit filename="..\..\WDL\zlib\zutil.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\WDL\zlib\zutil.h" />
+		<Extensions>
+			<code_completion />
+			<debugger />
+		</Extensions>
+	</Project>
+</CodeBlocks_project_file>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter.cpp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,494 @@
+// 
+// AccessiblePeakMeter.cpp
+//
+// Author: Fiore Martin 
+// Started from IPlugMultiTargets example in WDL-OL, by Oli Larkin - https://github.com/olilarkin/wdl-ol
+//
+// Licensed under the Cockos WDL License, see README.txt
+//
+
+#include "AccessiblePeakMeter.h"
+#include "IPlug_include_in_plug_src.h"
+#include "resource.h"
+
+
+#include "IControl.h"
+#include "IBitmapMonoText.h"
+#include "AccessiblePeakMeter_controls.h"
+
+#include <memory>
+
+inline double midi2Freq(int note) {
+	return 440. * pow(2., (note - 69.) / 12.);
+}
+
+double toDBMeter(double val, double range)
+{
+	double db;
+	if (val > 0)
+		db = ::AmpToDB(val);
+	else
+		db = -999;
+	return BOUNDED((db + 60) / range,0,1);
+}
+
+/* reference points for controls layout, by changing these numbers only
+the widgets can be moved around and all the other bits (top/left/right
+borders, labels etc.) will follow. X and Y refer to the top-left coord  */
+enum ELayout {
+	lDryX = 20,
+	lDryY = 10,
+	lWetX = 85,
+	lWetY = 10,
+
+	lFaderLen = 190,
+	lPeakMeterX = 180,
+	lPeaklMeterY = 30,
+
+	lSonifTypeX = 20,
+	lSonifTypeY = 200,
+
+	lDecayRateX = 20,
+	lDecayRateY = 90
+};
+
+enum EParams
+{
+	kDry = 0,
+	kWet,
+	kThreshold,
+	kSonificationType,
+	kMeterDecayRate,
+	kNumParams
+};
+
+AccessiblePeakMeter::AccessiblePeakMeter(IPlugInstanceInfo instanceInfo)
+  : IPLUG_CTOR(kNumParams, NUM_PRESETS, instanceInfo),
+  mDry(DRY_DEFAULT),
+  mWet(WET_DEFAULT),
+  mMeterDecayRate(1.0),
+  mThreshold(1.0),
+  mSampleRate(44100.),
+  mSonificationType(SONIFICATION_TYPE_CLIPPING)
+
+{
+  TRACE;
+  
+  //arguments are: name, defaultVal, minVal, maxVal, step, label
+  GetParam(kDry)->InitDouble("Dry", DRY_DEFAULT, -61.0, 0., 0.2, "dB");
+  GetParam(kDry)->SetDisplayText(-61.0, " -inf");
+  GetParam(kWet)->InitDouble("Wet", WET_DEFAULT, -61.0, 0., 0.2, "dB");
+  GetParam(kWet)->SetDisplayText(-61.0, " -inf");
+  GetParam(kThreshold)->InitDouble("Threshold", 0.0, -60.0, 6.2, 0.2, "dB");
+  GetParam(kSonificationType)->InitEnum("Sonification Type", SONIFICATION_TYPE_DEFAULT, 2);
+  GetParam(kSonificationType)->SetDisplayText(SONIFICATION_TYPE_CLIPPING, "Clipping");
+  GetParam(kSonificationType)->SetDisplayText(SONIFICATION_TYPE_CONTINUOUS, "Continuous");
+  
+  GetParam(kMeterDecayRate)->InitDouble("Decay", 1.0, 0.05, 1.0, 0.05, "sec.");
+  
+  IGraphics* pGraphics = MakeGraphics(this, GUI_WIDTH, GUI_HEIGHT);
+  pGraphics->AttachBackground(BG_ID, BG_FN);
+
+  /* load bitmaps for fader, knob and switch button */
+  IBitmap knob = pGraphics->LoadIBitmap(KNOB_ID, KNOB_FN, NUM_KNOB_FRAMES);
+  IBitmap faderBmap = pGraphics->LoadIBitmap(FADER_ID, FADER_FN);
+  IBitmap aSwitch = pGraphics->LoadIBitmap(SWITCH_ID, SWITCH_FN,2);
+
+  //pGraphics->AttachKeyCatcher(new IKeyCatcher(this, IRECT(0, 0, GUI_WIDTH, GUI_HEIGHT)));
+
+  /* text has info about the font-size, font-type etc. */
+  IText text = IText(14);
+  /* attach sonification type switch to the GUI */
+  pGraphics->AttachControl(new ISwitchPopUpControl(this, lSonifTypeX ,lSonifTypeY, kSonificationType, &aSwitch));
+  pGraphics->AttachControl(new ITextControl(this, IRECT(lSonifTypeX+10, lSonifTypeY - 20, lSonifTypeX + 110, lSonifTypeY ), &text, "Sonification Type"));
+  
+  /* attach dry and wet knobs to GUI */
+  pGraphics->AttachControl(new IKnobMultiControlText(this, IRECT(lDryX, lDryY, lDryX + 52, lDryY + 48 + 20 + 20), kDry, &knob, &text, 27));
+  pGraphics->AttachControl(new IKnobMultiControlText(this, IRECT(lWetX, lWetY, lWetX + 52, lWetY + 48 + 20 + 20), kWet, &knob, &text, 27));
+
+  /* attach decay rate knob to the GUI */
+  pGraphics->AttachControl(new IKnobMultiControlText(this, IRECT(lDecayRateX, lDecayRateY, lDecayRateX + 48, lDecayRateY + 48 + 20 + 20), kMeterDecayRate, &knob, &text, 33));
+
+  /* attach fader display, which shows the fader value, to GUI */
+  ITextControl *faderText = new ITextControl(this, IRECT(lPeakMeterX+60, lPeaklMeterY + lFaderLen, lPeakMeterX + faderBmap.W + 95, lPeaklMeterY + lFaderLen + 20), &text);
+  pGraphics->AttachControl(faderText);
+
+  /* attach the fader to GUI */
+  pGraphics->AttachControl(new IFaderVertText(this, lPeakMeterX, lPeaklMeterY, lFaderLen, kThreshold, &faderBmap, faderText));
+
+  pGraphics->AttachControl(new ITextControl(this, IRECT(lPeakMeterX, lPeaklMeterY - 20, lPeakMeterX + 100, lPeaklMeterY), &text, "Peak Level Meter"));
+  pGraphics->AttachControl(new ITextControl(this, IRECT(lPeakMeterX-20, lPeaklMeterY + lFaderLen, lPeakMeterX + 75, lPeaklMeterY + lFaderLen + 20), &text, "Threshold: "));
+
+  /* attach peak meters to GUI */
+  /* half the bitmap height is added to the peak meters on both top and bottom to prevent the fader 
+     - a triangle pointing at half the height of the bitmap - from overflowing the peak meters */
+  int halfFaderBmapLen = faderBmap.W / 2;
+  mMeterIdx[0] = pGraphics->AttachControl(new IPeakMeterVert(this, IRECT(lPeakMeterX + 25, lPeaklMeterY + halfFaderBmapLen, lPeakMeterX + 45, lPeaklMeterY + 170 + halfFaderBmapLen),
+	  GetParam(kThreshold)->GetDefaultNormalized()));
+  mMeterIdx[1] = pGraphics->AttachControl(new IPeakMeterVert(this,
+	  IRECT(lPeakMeterX + 50, lPeaklMeterY + halfFaderBmapLen, lPeakMeterX + 70, lPeaklMeterY + lFaderLen - halfFaderBmapLen), GetParam(kThreshold)->GetDefaultNormalized()));
+
+  AttachGraphics(pGraphics);
+
+  //kDry, kWet, kThreshold, kSonificationType, kMeterDecayRate,
+  MakePreset("Detect Clipping", DRY_DEFAULT, WET_DEFAULT, THRESHOLD_DEFAULT, SONIFICATION_TYPE_CLIPPING, METERDECAY_DEFAULT);
+  MakePreset("Sonify Audio", DRY_DEFAULT, WET_DEFAULT, THRESHOLD_DEFAULT, SONIFICATION_TYPE_CONTINUOUS, METERDECAY_DEFAULT);
+
+}
+
+AccessiblePeakMeter::~AccessiblePeakMeter() { }
+
+
+void AccessiblePeakMeter::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
+{
+	if(mSonificationType == SONIFICATION_TYPE_CONTINUOUS) {
+		 addContinuousSonification(inputs, outputs, nFrames);
+	} else {
+		addClippingSonification(inputs, outputs, nFrames);
+	}
+}
+
+
+void AccessiblePeakMeter::Reset()
+{
+  TRACE;
+  IMutexLock lock(this);
+
+  mSampleRate = GetSampleRate();
+  
+  for (int i = 0; i < MAX_CHANNELS; i++) {
+      mPrevPeak[i] = 0.0;
+  }
+ 
+  if (!sDacThread.started){
+	  sDacThread.started = true;
+	  sDacThread.t = std::move(std::thread(DacRoutine));
+  }  
+}
+
+void AccessiblePeakMeter::OnParamChange(int paramIdx)
+{
+  IMutexLock lock(this);
+
+  switch (paramIdx)
+  {
+	  case kDry :
+	  if (GetParam(kDry)->Value() < -60.5){
+		  mDry = 0.0;
+	  }
+	  else {
+		  mDry = ::DBToAmp(GetParam(kDry)->Value());
+	  }
+	  break;
+
+  case kWet:
+	  if (GetParam(kWet)->Value() < -60.5){
+		  mWet = 0.0;
+	  }
+	  else{
+		  mWet = ::DBToAmp(GetParam(kWet)->Value());
+	  }
+	  break;
+
+    case kThreshold:
+	  mThreshold = GetParam(kThreshold)->DBToAmp();
+      break;
+
+	case kMeterDecayRate :
+		mMeterDecayRate = 1.0 / GetParam(kMeterDecayRate)->Value();
+	  break;
+
+	case kSonificationType:
+		mSonificationType = GetParam(kSonificationType)->Int();
+		
+		for (int i = 0; i < MAX_CHANNELS; i++) {
+			mPrevPeak[i] = 0.0;
+		}
+
+		sDacMutex.lock();
+		sDacSynced.sonificationType = mSonificationType;
+		sDacMutex.unlock();
+		
+		break;
+
+    default:
+      break;
+  }
+}
+
+void AccessiblePeakMeter::addClippingSonification(double** inputs, double** outputs, int nFrames) {
+	// Mutex is already locked for us.
+
+	double clippingDiff[MAX_CHANNELS] = { 0.0, 0.0 };
+
+	for (unsigned int channel = 0; channel < NInChannels(); channel++) {
+		double* in = inputs[channel];
+		double* out = outputs[channel];
+		double peak = 0.0;
+
+		/* find the max absolute value in the block of samples */
+		for (int offset = 0; offset < nFrames; ++offset, ++in, ++out) {
+			/* find the peak of this block */
+			peak = IPMAX(peak, fabs(*in));
+			/* write the input buffer to the output */
+			*out = mDry * (*in); 
+		}
+
+		if (peak > mThreshold) {
+			double difftoThrs = fabs(::AmpToDB(peak) - ::AmpToDB(mThreshold));
+			/* clipDiff will be rounded downward later, but if it's very very
+			close to the ceil, then let it be the ceil.
+			*/
+			const double ceilClippingDiff = ceil(difftoThrs);
+			if (ceilClippingDiff - difftoThrs < CLIPPING_CEILING_SNAP){
+				difftoThrs = ceilClippingDiff;
+			}
+
+			clippingDiff[channel] = BOUNDED(difftoThrs, 0.0, 12.0);
+		}
+
+		/* now draw the peak meter with the maximum of this block of samples */
+		const double deltaT = nFrames / mSampleRate;
+		const double decayAmount = deltaT * mMeterDecayRate;
+
+		peak = ::toDBMeter(peak, DB_RANGE);
+
+		/* max between new peak and old peak decay wins */
+		peak = IPMAX(peak, mPrevPeak[channel] - decayAmount);
+		
+		/* save the peaks for next block of samples */
+		mPrevPeak[channel] = peak;
+		
+
+		/* update the GUI */
+		if (GetGUI()){
+			GetGUI()->SetControlFromPlug(mMeterIdx[channel], peak);
+		}
+	}
+
+	/* pass the data related to this block over to the sonification thread */
+	sDacMutex.lock();
+	sDacSynced.wet = mWet;
+	sDacSynced.maxClippingDiff[0] = clippingDiff[0];
+	sDacSynced.maxClippingDiff[1] = clippingDiff[1];
+	sDacMutex.unlock();
+	
+}
+
+void AccessiblePeakMeter::addContinuousSonification(double** inputs, double** outputs, int nFrames) {
+	// Mutex is already locked for us.
+	
+	const int nChannels = NInChannels();
+
+	const double deltaT = nFrames / mSampleRate;
+	const double decayAmount = deltaT * mMeterDecayRate;
+	double sonifyFreq[MAX_CHANNELS] = {0.0, 0.0};
+
+	for (int channel = 0; channel < nChannels; channel++){
+
+		double peak = 0.0;
+		double *in = inputs[channel];
+		double *out = outputs[channel];
+
+		/* find the max absolute value in the block of samples and write output */
+		for (int offset = 0; offset < nFrames; ++offset, ++in, ++out) {
+			/* find the peak of this block */
+			peak = IPMAX(peak, fabs(*in));
+			/* write the input buffer to the output */
+			*out = mDry * (*in);
+		}
+
+		/* pick the max between new audio and peak meter decaying */
+		peak = ::toDBMeter(peak, DB_RANGE);
+		peak = IPMAX(peak, mPrevPeak[channel] - decayAmount); 
+
+		/* set the sonification frequency according to the last peak value */
+		sonifyFreq[channel] = SONIFICATION_RANGE * peak;
+ 
+		/* save the peaks for next block of samples */
+		mPrevPeak[channel] = peak;
+
+		/* update the GUI */
+		if (GetGUI()){
+			GetGUI()->SetControlFromPlug(mMeterIdx[channel], peak);
+		}
+
+	}
+
+	/* pass the data related to this block over to the sonification thread */
+	sDacMutex.lock();
+	sDacSynced.sonifFreq[0] = sonifyFreq[0];
+	sDacSynced.sonifFreq[1] = sonifyFreq[1];
+	sDacSynced.wet = mWet;
+	sDacMutex.unlock();
+}
+
+/* Global scope function executed by the thread that plays the sonification to the dac */
+void DacRoutine(){
+
+	/* the sound card handle */
+	std::unique_ptr<stk::RtWvOut> sDac;
+
+	try {
+		// Define and open the default realtime output device for two-channels playback
+		sDac.reset(new stk::RtWvOut(MAX_CHANNELS, stk::Stk::sampleRate(), 0, DAC_BUFFER_SIZE));
+	}
+	catch (stk::StkError &) {
+		exit(1);
+	}
+	
+	/* buffer to calculate the blocks of DAC_BUFFER_SIZE samples.
+	   The content of the buffer is then fed to the sound card           
+	  */
+	stk::StkFrames frames(DAC_BUFFER_SIZE, MAX_CHANNELS);
+
+	while (true){
+
+		/*  init local variables to be filled with shared variables' content */
+		double freqs[MAX_CHANNELS] = { 0.0, 0.0 };
+		double clippingDiffs[MAX_CHANNELS] = { 0.0, 0.0 };
+		double wet = 0.0;
+		bool die = false;
+		int sonificationType;
+
+		/* read the shared variables all together into local variables */
+		sDacMutex.lock();
+
+		sonificationType = sDacSynced.sonificationType;
+		
+		for (int i = 0; i < MAX_CHANNELS; i++){
+			freqs[i] = sDacSynced.sonifFreq[i];
+			clippingDiffs[i] = sDacSynced.maxClippingDiff[i];
+		}
+
+		wet = sDacSynced.wet;
+
+		die = sDacSynced.die;
+
+		sDacMutex.unlock();
+
+		/* check if the thread has to stop. Called when the user exits the Daw */
+		if (die){
+			return;
+		}
+
+		/* reset the ugen if sonification type has changed */
+		if (sonificationType != sPrevSonificationType) {
+
+			for (int i = 0; i < MAX_CHANNELS; i++){
+				sSonification.ugen[i].reset();
+				sSonification.ugen[i].setFrequency(sonificationType == SONIFICATION_TYPE_CLIPPING ? 440 : 0);
+			}
+		
+			sPrevSonificationType = sonificationType;
+		}
+
+		if (sonificationType == SONIFICATION_TYPE_CONTINUOUS) {
+			/* write the next block of samples to send to the soundcard */
+			for (int nFrame = 0; nFrame < DAC_BUFFER_SIZE; nFrame++){
+				for (int channel = 0; channel < MAX_CHANNELS; channel++){
+
+					sSonification.ugen[channel].setFrequency(freqs[channel]);
+					/* If level goes below audible level just hush the sonification.  *
+					* this avoids DC offset when sonification frequency gets too low. *
+					* Use an envelope to bring the sonification volume down gently    */
+					if (freqs[channel] < AccessiblePeakMeter::MIN_SONIFICATION_FREQ){
+
+						if (sSonification.continous.isOn[channel]){ // if it's on and level's low, turn it off 
+							sSonification.continous.isOn[channel] = false;
+							sSonification.continous.envelope[channel].setTarget(0.0);
+						}
+
+					}
+					else if (!sSonification.continous.isOn[channel]){ // if it's off and level's high, turn it on
+
+						sSonification.continous.envelope[channel].setValue(1.0);
+						sSonification.continous.isOn[channel] = true;
+
+					}
+
+					double tick = sSonification.ugen[channel].tick();
+					tick *= sSonification.continous.envelope[channel].tick(); // apply envelope 
+					tick *= wet; // apply wet parameter, controlled by the user 
+					frames(nFrame, channel) = tick;
+				}
+			}
+		}
+		else { // sonificationType = AccessiblePeakMeter::SONIFICATION_TYPE_CLIPPING
+
+			for (int channel = 0; channel < MAX_CHANNELS; channel++){
+
+				if (clippingDiffs[channel] > 0.0){
+					if (clippingDiffs[channel] > sSonification.clipping.maxDiff[channel]){
+						sSonification.clipping.maxDiff[channel] = clippingDiffs[channel];
+					}
+
+					/* sonify the difference between the amplitude and threshold *
+					* one db (rounded downward) is one tone, up to one octave                      */
+					sSonification.ugen[channel].setFrequency(midi2Freq(69 + (int)(sSonification.clipping.maxDiff[channel])));
+					sSonification.clipping.envelope[channel].keyOn();
+				}
+
+			}
+
+			for (int nFrame = 0; nFrame < DAC_BUFFER_SIZE; nFrame++){
+				for (int channel = 0; channel < MAX_CHANNELS; channel++){
+
+					/* when attack is done switch immediately to RELEASE (keyOff) *
+					* this way the evelope goes like attack->release->silence     */
+					if (sSonification.clipping.envelope[channel].getState() == stk::ADSR::DECAY) {
+						sSonification.clipping.envelope[channel].keyOff();
+					}
+
+					/* write the sonification in the frames object */
+					if (sSonification.clipping.envelope[channel].getState() == stk::ADSR::ATTACK ||
+						sSonification.clipping.envelope[channel].getState() == stk::ADSR::RELEASE) {
+
+						const double env = sSonification.clipping.envelope[channel].tick();
+						double tick = sSonification.ugen[channel].tick() * env;
+						tick *= wet;
+						frames(nFrame, channel) = tick;
+
+					}
+					else { // no sonification
+
+						sSonification.clipping.maxDiff[channel] = 0.0; // reset max clipping diff 
+						frames(nFrame, channel) = 0.0;
+
+					}
+				}
+			}
+
+		}
+
+		/* play this block to the default soundcard */
+		sDac->tick(frames);
+	}
+
+}
+
+//Called by the standalone wrapper if someone clicks about
+bool AccessiblePeakMeter::HostRequestingAboutBox()
+{
+  IMutexLock lock(this);
+  if(GetGUI())
+  {
+	// do nothing 
+  }
+  return true;
+}
+
+
+
+const double AccessiblePeakMeter::DRY_DEFAULT = 0.0;
+const double AccessiblePeakMeter::WET_DEFAULT = -6.0;
+const int AccessiblePeakMeter::SONIFICATION_TYPE_DEFAULT = 1;
+const double AccessiblePeakMeter::METERDECAY_DEFAULT = 60.0;
+const double AccessiblePeakMeter::THRESHOLD_DEFAULT = 0.0;
+
+const double AccessiblePeakMeter::DB_RANGE = 66.0;
+const double AccessiblePeakMeter::SONIFICATION_RANGE = 2000;
+const double AccessiblePeakMeter::MIN_SONIFICATION_FREQ = 20.0;
+const double AccessiblePeakMeter::CLIPPING_CEILING_SNAP = 0.05;
+const int AccessiblePeakMeter::NUM_KNOB_FRAMES = 60;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter.exp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,2 @@
+_AccessiblePeakMeter_Entry
+_AccessiblePeakMeter_ViewEntry
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,201 @@
+// 
+// AccessiblePeakMeter.h
+//
+// Author: Fiore Martin 
+// Started from IPlugMultiTargets example in WDL-OL, by Oli Larkin - https://github.com/olilarkin/wdl-ol
+//
+// Licensed under the Cockos WDL License, see README.txt
+//
+
+#ifndef __ACCESSIBLEPEAKMETER__
+#define __ACCESSIBLEPEAKMETER__
+
+#include "IPlug_include_in_plug_hdr.h"
+#include "stk/include/SineWave.h"
+#include "stk/include/Envelope.h"
+#include "stk/include/ADSR.h"
+#include "stk/include/RtAudio.h"
+#include "stk/include/RtWvOut.h"
+
+#include <thread>
+#include <mutex>
+
+
+const int DAC_BUFFER_SIZE = 64;
+const int SONIFICATION_TYPE_CLIPPING = 1;
+const int SONIFICATION_TYPE_CONTINUOUS = 0;
+const double BEEP_TIME = 0.2;
+const int MAX_CHANNELS = 2;
+
+/*
+This is a slightly hacked version of the AccessiblePeakMeter. The sonification is sent to 
+the defualt audio card rather than to the plugin output. The input audio signal is still 
+routed to the plugin out put with nomodification besides the amplitude, modified according
+to the dry parameter. 
+
+When Reset() is called for the first time on the plugin, a new thread is spawned. 
+The VST plugin then continuously shares information about the input audio with the thread.
+The thread continously polls this information and plays the sonification on the default audio interface. 
+
+DacRoutine() : is the function execute by the new thread
+DacSynced : is the struct with all shared variables between the new thread and the VST plugin 
+Sonification: is the structure with all the sonification stuff. In this version it is only 
+accessed by the new thread. 
+
+DacThread struct does RAAI on the resource "thread"
+
+*/
+
+
+
+/* DacRouting is the function executed by the thread that plays the sonification to the dac */
+void DacRoutine();
+
+/* the sonification struct contains all the variables for sonification.
+   It is accessed exclusively by the sonification thread */
+struct Sonification {
+	stk::SineWave ugen[MAX_CHANNELS];
+
+	/* resets all the ugens. Type and ugen freq are not affected by reset
+	as well as sample rate, when srate is less than 0  */
+	void reset(double srate = -1.0){
+		for (int i = 0; i < MAX_CHANNELS; i++){
+			ugen[i].reset();
+
+			/* continous sonification */
+			continous.isOn[i] = true;
+			stk::Envelope & coe = continous.envelope[i];
+			coe.setValue(1.0); // setValue also sets the target
+			coe.setTime(0.2);
+
+			/* clipping sonification */
+			clipping.maxDiff[i] = 0.0;
+			stk::ADSR & cle = clipping.envelope[i];
+			cle.setValue(0.0);
+			cle.setReleaseTime(BEEP_TIME);
+			cle.setAttackTime(0.01);
+			cle.setSustainLevel(1);
+
+			/*
+			the sample is fixed to 44100 when the handle to the soundcard is created 
+			the sonification is independent from changes in the daw sample rate anyway 
+			if (srate > 0.0){
+				ugen[i].setSampleRate(srate);
+				coe.setSampleRate(srate);
+				cle.setSampleRate(srate);
+			}
+			*/
+		}
+	}
+
+	struct Continous {
+		stk::Envelope envelope[MAX_CHANNELS];
+		bool isOn[MAX_CHANNELS];
+	} continous;
+
+	struct Clipping {
+		double maxDiff[MAX_CHANNELS];
+		stk::ADSR envelope[MAX_CHANNELS];
+	} clipping;
+
+	Sonification() {
+		reset();
+	}
+} sSonification;
+
+/* this structure is used to pass information back and forth between 
+  the puginthread and the sonification thread, with direct access  to the sound card */
+struct DacSynced {
+	bool die;
+	double wet;
+	double sonifFreq[MAX_CHANNELS];
+	int type;
+	double maxClippingDiff[MAX_CHANNELS];
+	int sonificationType;
+	DacSynced() 
+		: die(false),
+		wet(0.5),
+		sonificationType( SONIFICATION_TYPE_CLIPPING )
+	{
+		for (int i = 0; i < MAX_CHANNELS; i++){
+			sonifFreq[i] = 0.0;
+			maxClippingDiff[i] = 0.0;
+		}
+	}
+} sDacSynced;
+
+
+
+/* mutex to sync the vst plugin thread with the thread
+   that writes directly into the soundcard (DacThread)
+ */
+std::mutex sDacMutex;
+
+
+/*sPrevSonificationType keeps track of the sonification type. Useful for DacThread 
+to assess whether the sonification has changed from the last loop cycle */
+int sPrevSonificationType = SONIFICATION_TYPE_CLIPPING;
+
+struct DacThread {
+	std::thread t;
+	bool started = false;
+
+	/* when this struct goes out of scope (user     *
+	 * exits daw) The thread is stopped and joined. */
+	~DacThread(){
+		sDacMutex.lock();
+		sDacSynced.die = true;
+		sDacMutex.unlock();
+
+		if (t.joinable())
+			t.join();
+	}
+
+} sDacThread;
+ 
+class AccessiblePeakMeter : public IPlug
+{
+public:
+
+	AccessiblePeakMeter(IPlugInstanceInfo instanceInfo);
+	~AccessiblePeakMeter();
+
+	void Reset();
+	void OnParamChange(int paramIdx);
+
+	void ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames);
+	bool HostRequestingAboutBox();
+
+	static const double DRY_DEFAULT;
+	static const double WET_DEFAULT;
+	static const int SONIFICATION_TYPE_DEFAULT;
+	static const double METERDECAY_DEFAULT;
+	static const double THRESHOLD_DEFAULT;
+	static const double BEEP_TIME;
+	static const double DB_RANGE;
+	static const double SONIFICATION_RANGE;
+	static const int NO_BEEP;
+	static const int NUM_PRESETS = 2;
+	static const double MIN_SONIFICATION_FREQ;
+	static const int NUM_KNOB_FRAMES;
+	static const double CLIPPING_CEILING_SNAP;
+
+private:
+	/* parameters on the GUI */
+	double mDry;
+	double mWet;
+	double mMeterDecayRate;
+	double mThreshold;
+
+	double mSampleRate;
+	
+	double mPrevPeak[MAX_CHANNELS];
+	int mMeterIdx[MAX_CHANNELS];
+
+	int mSonificationType;
+	
+	void addContinuousSonification(double** inputs, double** outputs, int nFrames);
+	void addClippingSonification(double** inputs, double** outputs, int nFrames);
+};
+
+#endif //__ACCESSIBLEPEAKMETER__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter.props	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ImportGroup Label="PropertySheets">
+    <Import Project="..\..\common.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros">
+    <BINARY_NAME>AccessiblePeakMeter</BINARY_NAME>
+    <APP_DEFS>SA_API;__WINDOWS_DS__;__WINDOWS_MM__;__WINDOWS_ASIO__;</APP_DEFS>
+    <VST_DEFS>VST_API;VST_FORCE_DEPRECATED;</VST_DEFS>
+    <VST3_DEFS>VST3_API</VST3_DEFS>
+    <DEBUG_DEFS>_DEBUG;</DEBUG_DEFS>
+    <RELEASE_DEFS>NDEBUG;</RELEASE_DEFS>
+    <TRACER_DEFS>TRACER_BUILD;NDEBUG;</TRACER_DEFS>
+    <ADDITIONAL_INCLUDES>$(ProjectDir)\..\..\..\MyDSP\;</ADDITIONAL_INCLUDES>
+    <APP_INCLUDES>..\..\ASIO_SDK;..\..\WDL\rtaudiomidi;</APP_INCLUDES>
+    <APP_LIBS>dsound.lib;winmm.lib;Comctl32.lib;</APP_LIBS>
+    <VST3_INCLUDES>..\..\VST3_SDK;</VST3_INCLUDES>
+    <AAX_INCLUDES>.\..\..\AAX_SDK\Interfaces;.\..\..\AAX_SDK\Interfaces\ACF;.\..\..\WDL\IPlug\AAX</AAX_INCLUDES>
+    <AAX_DEFS>AAX_API;_WINDOWS;WIN32;_WIN32;WINDOWS_VERSION;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE</AAX_DEFS>
+    <AAX_LIBS>lice.lib;wininet.lib;odbc32.lib;odbccp32.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comctl32.lib;</AAX_LIBS>
+    <RTAS_INCLUDES>.\..\..\WDL\IPlug\RTAS;.\</RTAS_INCLUDES>
+    <RTAS_DEFS>RTAS_API;_HAS_ITERATOR_DEBUGGING=0;_SECURE_SCL=0;_WINDOWS;WIN32;_WIN32;WINDOWS_VERSION;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE</RTAS_DEFS>
+    <RTAS_LIBS>comdlg32.lib;uuid.lib;msimg32.lib;odbc32.lib;odbccp32.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib</RTAS_LIBS>
+  </PropertyGroup>
+  <PropertyGroup>
+    <TargetName>$(BINARY_NAME)</TargetName>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ADDITIONAL_INCLUDES);..\..\WDL;..\..\WDL\lice;..\..\WDL\IPlug</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>IPlug.lib;lice.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <BuildMacro Include="BINARY_NAME">
+      <Value>$(BINARY_NAME)</Value>
+    </BuildMacro>
+    <BuildMacro Include="APP_DEFS">
+      <Value>$(APP_DEFS)</Value>
+    </BuildMacro>
+    <BuildMacro Include="VST_DEFS">
+      <Value>$(VST_DEFS)</Value>
+    </BuildMacro>
+    <BuildMacro Include="VST3_DEFS">
+      <Value>$(VST3_DEFS)</Value>
+    </BuildMacro>
+    <BuildMacro Include="DEBUG_DEFS">
+      <Value>$(DEBUG_DEFS)</Value>
+    </BuildMacro>
+    <BuildMacro Include="RELEASE_DEFS">
+      <Value>$(RELEASE_DEFS)</Value>
+    </BuildMacro>
+    <BuildMacro Include="TRACER_DEFS">
+      <Value>$(TRACER_DEFS)</Value>
+    </BuildMacro>
+    <BuildMacro Include="ADDITIONAL_INCLUDES">
+      <Value>$(ADDITIONAL_INCLUDES)</Value>
+    </BuildMacro>
+    <BuildMacro Include="APP_INCLUDES">
+      <Value>$(APP_INCLUDES)</Value>
+    </BuildMacro>
+    <BuildMacro Include="APP_LIBS">
+      <Value>$(APP_LIBS)</Value>
+    </BuildMacro>
+    <BuildMacro Include="VST3_INCLUDES">
+      <Value>$(VST3_INCLUDES)</Value>
+    </BuildMacro>
+    <BuildMacro Include="AAX_INCLUDES">
+      <Value>$(AAX_INCLUDES)</Value>
+    </BuildMacro>
+    <BuildMacro Include="AAX_DEFS">
+      <Value>$(AAX_DEFS)</Value>
+    </BuildMacro>
+    <BuildMacro Include="AAX_LIBS">
+      <Value>$(AAX_LIBS)</Value>
+    </BuildMacro>
+    <BuildMacro Include="RTAS_INCLUDES">
+      <Value>$(RTAS_INCLUDES)</Value>
+    </BuildMacro>
+    <BuildMacro Include="RTAS_DEFS">
+      <Value>$(RTAS_DEFS)</Value>
+    </BuildMacro>
+    <BuildMacro Include="RTAS_LIBS">
+      <Value>$(RTAS_LIBS)</Value>
+    </BuildMacro>
+  </ItemGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter.rc	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,81 @@
+#include "resource.h"
+
+KNOB_ID       PNG KNOB_FN
+BG_ID         PNG BG_FN
+FADER_ID      PNG FADER_FN
+SWITCH_ID     PNG SWITCH_FN
+
+#ifdef SA_API
+//Standalone stuff
+#include <windows.h>
+
+IDI_ICON1                ICON    DISCARDABLE     "resources\AccessiblePeakMeter.ico"
+
+IDD_DIALOG_MAIN DIALOG DISCARDABLE  0, 0, GUI_WIDTH, GUI_HEIGHT
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
+CAPTION "AccessiblePeakMeter2S"
+MENU IDR_MENU1
+FONT 8, "MS Sans Serif"
+BEGIN
+//   EDITTEXT        IDC_EDIT1,59,50,145,14,ES_AUTOHSCROLL
+//   LTEXT           "Enter some text here:",IDC_STATIC,59,39,73,8
+END
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+IDD_DIALOG_PREF DIALOG DISCARDABLE 0, 0, 223, 309
+STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
+CAPTION "Preferences"
+FONT 8, "MS Sans Serif"
+{
+    DEFPUSHBUTTON   "OK", IDOK, 110, 285, 50, 14
+    PUSHBUTTON      "Apply", IDAPPLY, 54, 285, 50, 14
+    PUSHBUTTON      "Cancel", IDCANCEL, 166, 285, 50, 14
+    COMBOBOX        IDC_COMBO_AUDIO_DRIVER, 20, 35, 100, 100, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    LTEXT           "Driver Type", IDC_STATIC, 22, 25, 38, 8, SS_LEFT
+    COMBOBOX        IDC_COMBO_AUDIO_IN_DEV, 20, 65, 100, 200, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    LTEXT           "Input Device", IDC_STATIC, 20, 55, 42, 8, SS_LEFT
+    COMBOBOX        IDC_COMBO_AUDIO_OUT_DEV, 20, 95, 100, 200, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    LTEXT           "Output Device", IDC_STATIC, 20, 85, 47, 8, SS_LEFT
+    COMBOBOX        IDC_COMBO_AUDIO_IOVS, 135, 35, 65, 100, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    LTEXT           "IO Vector Size", IDC_STATIC, 137, 25, 46, 8, SS_LEFT
+    COMBOBOX        IDC_COMBO_AUDIO_SIGVS, 135, 65, 65, 100, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    LTEXT           "Signal Vector Size", IDC_STATIC, 135, 55, 58, 8, SS_LEFT
+    COMBOBOX        IDC_COMBO_AUDIO_SR, 135, 95, 65, 200, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    LTEXT           "Sampling Rate", IDC_STATIC, 135, 85, 47, 8, SS_LEFT
+    GROUPBOX        "Audio Device Settings", IDC_STATIC, 5, 10, 210, 170
+    PUSHBUTTON      "ASIO Config...", IDC_BUTTON_ASIO, 135, 155, 65, 14
+    COMBOBOX        IDC_COMBO_AUDIO_IN_L, 20, 125, 40, 200, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    LTEXT           "Input 1 (L)", IDC_STATIC, 20, 115, 33, 8, SS_LEFT
+    COMBOBOX        IDC_COMBO_AUDIO_IN_R, 65, 126, 40, 200, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    LTEXT           "Input 2 (R)", IDC_STATIC, 65, 115, 34, 8, SS_LEFT
+    COMBOBOX        IDC_COMBO_AUDIO_OUT_L, 20, 155, 40, 200, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    LTEXT           "Output 1 (L)", IDC_STATIC, 20, 145, 38, 8, SS_LEFT
+    COMBOBOX        IDC_COMBO_AUDIO_OUT_R, 65, 155, 40, 200, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    LTEXT           "Output 2 (R)", IDC_STATIC, 65, 145, 40, 8, SS_LEFT
+    GROUPBOX        "MIDI Device Settings", IDC_STATIC, 5, 190, 210, 85
+    COMBOBOX        IDC_COMBO_MIDI_OUT_DEV, 15, 250, 100, 200, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    LTEXT           "Output Device", IDC_STATIC, 15, 240, 47, 8, SS_LEFT
+    COMBOBOX        IDC_COMBO_MIDI_IN_DEV, 15, 220, 100, 200, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    LTEXT           "Input Device", IDC_STATIC, 15, 210, 42, 8, SS_LEFT
+    LTEXT           "Input Channel", IDC_STATIC, 125, 210, 45, 8, SS_LEFT
+    COMBOBOX        IDC_COMBO_MIDI_IN_CHAN, 125, 220, 50, 200, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    LTEXT           "Output Channel", IDC_STATIC, 125, 240, 50, 8, SS_LEFT
+    COMBOBOX        IDC_COMBO_MIDI_OUT_CHAN, 125, 250, 50, 200, CBS_DROPDOWNLIST | CBS_HASSTRINGS
+    AUTOCHECKBOX    "Mono Input", IDC_CB_MONO_INPUT, 135, 127, 56, 8
+}
+
+IDR_MENU1 MENU DISCARDABLE 
+BEGIN
+    POPUP "&File"
+    BEGIN
+//      MENUITEM SEPARATOR
+        MENUITEM "Preferences...",              ID_PREFERENCES
+        MENUITEM "&Quit",                       ID_QUIT
+    END
+    POPUP "&Help"
+    BEGIN
+        MENUITEM "&About",                      ID_ABOUT
+    END
+END
+
+#endif // SA_API
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter.sln	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,108 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2013 for Windows Desktop
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IPlug", "..\..\WDL\IPlug\IPlug.vcxproj", "{33958832-2FFD-49D8-9C13-5F0B26739E81}"
+	ProjectSection(ProjectDependencies) = postProject
+		{3059A12C-2A45-439B-81EC-201D8ED347A3} = {3059A12C-2A45-439B-81EC-201D8ED347A3}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lice", "..\..\WDL\lice\lice.vcxproj", "{3059A12C-2A45-439B-81EC-201D8ED347A3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AccessiblePeakMeter-vst2", "AccessiblePeakMeter-vst2.vcxproj", "{2EB4846A-93E0-43A0-821E-12237105168F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{3059A12C-2A45-439B-81EC-201D8ED347A3} = {3059A12C-2A45-439B-81EC-201D8ED347A3}
+		{33958832-2FFD-49D8-9C13-5F0B26739E81} = {33958832-2FFD-49D8-9C13-5F0B26739E81}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "..\..\VST3_SDK\base\win\base_vc10.vcxproj", "{5755CC40-C699-491B-BD7C-5D841C26C28D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AAXLibrary", "..\..\AAX_SDK\Libs\AAXLibrary\WinBuild\AAXLibrary.vcxproj", "{5E3D286E-BF0D-446A-AFEF-E800F283CE53}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PlugInLib", "..\..\PT9_SDK\AlturaPorts\TDMPlugIns\PlugInLibrary\WinBuild\PlugInLib.vcxproj", "{D2CE28FF-63B8-48BC-936D-33F365B4053F}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+		Tracer|Win32 = Tracer|Win32
+		Tracer|x64 = Tracer|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{33958832-2FFD-49D8-9C13-5F0B26739E81}.Debug|Win32.ActiveCfg = Debug|Win32
+		{33958832-2FFD-49D8-9C13-5F0B26739E81}.Debug|Win32.Build.0 = Debug|Win32
+		{33958832-2FFD-49D8-9C13-5F0B26739E81}.Debug|x64.ActiveCfg = Debug|x64
+		{33958832-2FFD-49D8-9C13-5F0B26739E81}.Debug|x64.Build.0 = Debug|x64
+		{33958832-2FFD-49D8-9C13-5F0B26739E81}.Release|Win32.ActiveCfg = Release|Win32
+		{33958832-2FFD-49D8-9C13-5F0B26739E81}.Release|Win32.Build.0 = Release|Win32
+		{33958832-2FFD-49D8-9C13-5F0B26739E81}.Release|x64.ActiveCfg = Release|x64
+		{33958832-2FFD-49D8-9C13-5F0B26739E81}.Release|x64.Build.0 = Release|x64
+		{33958832-2FFD-49D8-9C13-5F0B26739E81}.Tracer|Win32.ActiveCfg = Tracer|Win32
+		{33958832-2FFD-49D8-9C13-5F0B26739E81}.Tracer|Win32.Build.0 = Tracer|Win32
+		{33958832-2FFD-49D8-9C13-5F0B26739E81}.Tracer|x64.ActiveCfg = Tracer|x64
+		{33958832-2FFD-49D8-9C13-5F0B26739E81}.Tracer|x64.Build.0 = Tracer|x64
+		{3059A12C-2A45-439B-81EC-201D8ED347A3}.Debug|Win32.ActiveCfg = Debug|Win32
+		{3059A12C-2A45-439B-81EC-201D8ED347A3}.Debug|Win32.Build.0 = Debug|Win32
+		{3059A12C-2A45-439B-81EC-201D8ED347A3}.Debug|x64.ActiveCfg = Debug|x64
+		{3059A12C-2A45-439B-81EC-201D8ED347A3}.Debug|x64.Build.0 = Debug|x64
+		{3059A12C-2A45-439B-81EC-201D8ED347A3}.Release|Win32.ActiveCfg = Release|Win32
+		{3059A12C-2A45-439B-81EC-201D8ED347A3}.Release|Win32.Build.0 = Release|Win32
+		{3059A12C-2A45-439B-81EC-201D8ED347A3}.Release|x64.ActiveCfg = Release|x64
+		{3059A12C-2A45-439B-81EC-201D8ED347A3}.Release|x64.Build.0 = Release|x64
+		{3059A12C-2A45-439B-81EC-201D8ED347A3}.Tracer|Win32.ActiveCfg = Release|Win32
+		{3059A12C-2A45-439B-81EC-201D8ED347A3}.Tracer|Win32.Build.0 = Release|Win32
+		{3059A12C-2A45-439B-81EC-201D8ED347A3}.Tracer|x64.ActiveCfg = Release|x64
+		{3059A12C-2A45-439B-81EC-201D8ED347A3}.Tracer|x64.Build.0 = Release|x64
+		{2EB4846A-93E0-43A0-821E-12237105168F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{2EB4846A-93E0-43A0-821E-12237105168F}.Debug|Win32.Build.0 = Debug|Win32
+		{2EB4846A-93E0-43A0-821E-12237105168F}.Debug|x64.ActiveCfg = Debug|x64
+		{2EB4846A-93E0-43A0-821E-12237105168F}.Debug|x64.Build.0 = Debug|x64
+		{2EB4846A-93E0-43A0-821E-12237105168F}.Release|Win32.ActiveCfg = Release|Win32
+		{2EB4846A-93E0-43A0-821E-12237105168F}.Release|Win32.Build.0 = Release|Win32
+		{2EB4846A-93E0-43A0-821E-12237105168F}.Release|x64.ActiveCfg = Release|x64
+		{2EB4846A-93E0-43A0-821E-12237105168F}.Release|x64.Build.0 = Release|x64
+		{2EB4846A-93E0-43A0-821E-12237105168F}.Tracer|Win32.ActiveCfg = Tracer|Win32
+		{2EB4846A-93E0-43A0-821E-12237105168F}.Tracer|Win32.Build.0 = Tracer|Win32
+		{2EB4846A-93E0-43A0-821E-12237105168F}.Tracer|x64.ActiveCfg = Tracer|x64
+		{2EB4846A-93E0-43A0-821E-12237105168F}.Tracer|x64.Build.0 = Tracer|x64
+		{5755CC40-C699-491B-BD7C-5D841C26C28D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5755CC40-C699-491B-BD7C-5D841C26C28D}.Debug|Win32.Build.0 = Debug|Win32
+		{5755CC40-C699-491B-BD7C-5D841C26C28D}.Debug|x64.ActiveCfg = Debug|x64
+		{5755CC40-C699-491B-BD7C-5D841C26C28D}.Debug|x64.Build.0 = Debug|x64
+		{5755CC40-C699-491B-BD7C-5D841C26C28D}.Release|Win32.ActiveCfg = Release|Win32
+		{5755CC40-C699-491B-BD7C-5D841C26C28D}.Release|Win32.Build.0 = Release|Win32
+		{5755CC40-C699-491B-BD7C-5D841C26C28D}.Release|x64.ActiveCfg = Release|x64
+		{5755CC40-C699-491B-BD7C-5D841C26C28D}.Release|x64.Build.0 = Release|x64
+		{5755CC40-C699-491B-BD7C-5D841C26C28D}.Tracer|Win32.ActiveCfg = Release|Win32
+		{5755CC40-C699-491B-BD7C-5D841C26C28D}.Tracer|Win32.Build.0 = Release|Win32
+		{5755CC40-C699-491B-BD7C-5D841C26C28D}.Tracer|x64.ActiveCfg = Release|x64
+		{5755CC40-C699-491B-BD7C-5D841C26C28D}.Tracer|x64.Build.0 = Release|x64
+		{5E3D286E-BF0D-446A-AFEF-E800F283CE53}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5E3D286E-BF0D-446A-AFEF-E800F283CE53}.Debug|Win32.Build.0 = Debug|Win32
+		{5E3D286E-BF0D-446A-AFEF-E800F283CE53}.Debug|x64.ActiveCfg = Debug|x64
+		{5E3D286E-BF0D-446A-AFEF-E800F283CE53}.Debug|x64.Build.0 = Debug|x64
+		{5E3D286E-BF0D-446A-AFEF-E800F283CE53}.Release|Win32.ActiveCfg = Release|Win32
+		{5E3D286E-BF0D-446A-AFEF-E800F283CE53}.Release|Win32.Build.0 = Release|Win32
+		{5E3D286E-BF0D-446A-AFEF-E800F283CE53}.Release|x64.ActiveCfg = Release|x64
+		{5E3D286E-BF0D-446A-AFEF-E800F283CE53}.Release|x64.Build.0 = Release|x64
+		{5E3D286E-BF0D-446A-AFEF-E800F283CE53}.Tracer|Win32.ActiveCfg = Release|Win32
+		{5E3D286E-BF0D-446A-AFEF-E800F283CE53}.Tracer|Win32.Build.0 = Release|Win32
+		{5E3D286E-BF0D-446A-AFEF-E800F283CE53}.Tracer|x64.ActiveCfg = Release|x64
+		{5E3D286E-BF0D-446A-AFEF-E800F283CE53}.Tracer|x64.Build.0 = Release|x64
+		{D2CE28FF-63B8-48BC-936D-33F365B4053F}.Debug|Win32.ActiveCfg = Release|Win32
+		{D2CE28FF-63B8-48BC-936D-33F365B4053F}.Debug|Win32.Build.0 = Release|Win32
+		{D2CE28FF-63B8-48BC-936D-33F365B4053F}.Debug|x64.ActiveCfg = Debug|Win32
+		{D2CE28FF-63B8-48BC-936D-33F365B4053F}.Release|Win32.ActiveCfg = Release|Win32
+		{D2CE28FF-63B8-48BC-936D-33F365B4053F}.Release|Win32.Build.0 = Release|Win32
+		{D2CE28FF-63B8-48BC-936D-33F365B4053F}.Release|x64.ActiveCfg = Release|Win32
+		{D2CE28FF-63B8-48BC-936D-33F365B4053F}.Tracer|Win32.ActiveCfg = Release|Win32
+		{D2CE28FF-63B8-48BC-936D-33F365B4053F}.Tracer|Win32.Build.0 = Release|Win32
+		{D2CE28FF-63B8-48BC-936D-33F365B4053F}.Tracer|x64.ActiveCfg = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter.xcconfig	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,61 @@
+#include "../../common.xcconfig"
+
+//------------------------------
+// Global settings
+
+// the basename of the vst, vst3, app, component, dpm, aaxplugin
+BINARY_NAME = AccessiblePeakMeter
+
+ADDITIONAL_INCLUDES = // $(SRCROOT)/../../../MyDSP/
+
+// for jack headers
+//ADDITIONAL_APP_INCLUDES = /usr/local/include
+
+// Flags to pass to compiler for all builds
+GCC_CFLAGS = -Wno-write-strings
+
+//------------------------------
+// Preprocessor definitions
+
+// Preprocessor definitions for all VST builds
+VST_DEFS = VST_API VST_FORCE_DEPRECATED
+
+VST3_DEFS = VST3_API
+
+// Preprocessor definitions for all AU builds
+AU_DEFS = AU_API
+
+RTAS_DEFS = RTAS_API
+
+AAX_DEFS = AAX_API
+
+APP_DEFS = SA_API __MACOSX_CORE__ //__UNIX_JACK__
+
+IOS_DEFS = SA_API
+// Preprocessor definitions for all Debug builds
+DEBUG_DEFS = _DEBUG
+
+// Preprocessor definitions for all Release builds
+RELEASE_DEFS = NDEBUG //DEMO_VERSION
+
+// Preprocessor definitions for all Tracer builds
+TRACER_DEFS = TRACER_BUILD NDEBUG
+
+// Preprocessor definitions for cocoa uniqueness (all builds)
+// If you want to use swell inside of iplug, you need to make SWELL_APP_PREFIX unique too
+COCOA_DEFS = SWELL_CLEANUP_ON_UNLOAD COCOA_PREFIX=vAccessiblePeakMeter SWELL_APP_PREFIX=Swell_vAccessiblePeakMeter
+
+//------------------------------
+// Release build options
+
+//Enable/Disable Profiling code
+PROFILE = NO //NO, YES - enable this if you want to use shark to profile a plugin
+
+// GCC optimization level -
+// None: [-O0] Fast: [-O, -O1] Faster:[-O2] Fastest: [-O3] Fastest, smallest: Optimize for size. [-Os]
+RELEASE_OPTIMIZE = 3 //0,1,2,3,s
+
+//------------------------------
+// Debug build options
+DEBUG_OPTIMIZE = 0 //0,1,2,3,s
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter.xcodeproj/oli.pbxuser	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,1950 @@
+// !$*UTF8*$!
+{
+	089C1669FE841209C02AAC07 /* Project object */ = {
+		activeArchitecturePreference = i386;
+		activeBuildConfigurationName = Release;
+		activeExecutable = 4FD16A0A13B63081001D0217 /* APP */;
+		activeTarget = 4FD16A0813B63081001D0217 /* APP */;
+		addToTargets = (
+			4F7F5C4213E95EC8002918FD /* RTAS */,
+			4FB600121567CB0A0020189A /* AAX */,
+			4F3AE17812C0E5E2001FD7A4 /* AU */,
+			4F9828AA140A9EB700F3FCC1 /* VST3 */,
+			4F20EEC8132C69FE0030E34C /* VST2 */,
+			4FD16A0813B63081001D0217 /* APP */,
+		);
+		breakpoints = (
+		);
+		codeSenseManager = 4FE33FF410B4519D00B5FB70 /* Code sense */;
+		executables = (
+			4FD16A0A13B63081001D0217 /* APP */,
+			4F647528132A790E00D7E58C /* Auval */,
+			4F30A3F21117540400C237CE /* Aulab */,
+			4F8F27C7131A78AE007A37CF /* Garageband */,
+			4F94D77514EFB6B100DBF4C9 /* Logic */,
+			4FF6D80F12B28631001E9114 /* Live */,
+			4FF6D80D12B285DC001E9114 /* Reaper */,
+			4FF6D80B12B285AF001E9114 /* Cubase */,
+			4FF2407313FAB21200E40631 /* AudioMulch */,
+			4F2BB0CF141402D500564FFC /* Studio One */,
+			4F4AD1B61409A2BB0068A6D4 /* VST3TestHost */,
+			4F94D78014EFB6F800DBF4C9 /* VST3validator */,
+			4F7F5D0713E9676F002918FD /* ProTools Dev */,
+		);
+		perUserDictionary = {
+			"PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					20,
+					20,
+					198,
+					20,
+					99,
+					99,
+					29,
+					20,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXBreakpointsDataSource_ActionID,
+					PBXBreakpointsDataSource_TypeID,
+					PBXBreakpointsDataSource_BreakpointID,
+					PBXBreakpointsDataSource_UseID,
+					PBXBreakpointsDataSource_LocationID,
+					PBXBreakpointsDataSource_ConditionID,
+					PBXBreakpointsDataSource_IgnoreCountID,
+					PBXBreakpointsDataSource_ContinueID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.PBXBookmarksDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXBookmarksDataSource_NameID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					200,
+					200,
+					1283,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXBookmarksDataSource_LocationID,
+					PBXBookmarksDataSource_NameID,
+					PBXBookmarksDataSource_CommentsID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					22,
+					300,
+					830,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXExecutablesDataSource_ActiveFlagID,
+					PBXExecutablesDataSource_NameID,
+					PBXExecutablesDataSource_CommentsID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = 1;
+				PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Target_ColumnID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					20,
+					341,
+					20,
+					48,
+					43,
+					43,
+					20,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXFileDataSource_FiletypeID,
+					PBXFileDataSource_Filename_ColumnID,
+					PBXFileDataSource_Built_ColumnID,
+					PBXFileDataSource_ObjectSize_ColumnID,
+					PBXFileDataSource_Errors_ColumnID,
+					PBXFileDataSource_Warnings_ColumnID,
+					PBXFileDataSource_Target_ColumnID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.PBXFindDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXFindDataSource_LocationID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					200,
+					956,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXFindDataSource_MessageID,
+					PBXFindDataSource_LocationID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.PBXSymbolsDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXSymbolsDataSource_SymbolNameID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					16,
+					200,
+					50,
+					1273,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXSymbolsDataSource_SymbolTypeIconID,
+					PBXSymbolsDataSource_SymbolNameID,
+					PBXSymbolsDataSource_SymbolTypeID,
+					PBXSymbolsDataSource_ReferenceNameID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.XCSCMDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					20,
+					20,
+					1449,
+					20,
+					48,
+					43,
+					43,
+					20,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXFileDataSource_SCM_ColumnID,
+					PBXFileDataSource_FiletypeID,
+					PBXFileDataSource_Filename_ColumnID,
+					PBXFileDataSource_Built_ColumnID,
+					PBXFileDataSource_ObjectSize_ColumnID,
+					PBXFileDataSource_Errors_ColumnID,
+					PBXFileDataSource_Warnings_ColumnID,
+					PBXFileDataSource_Target_ColumnID,
+				);
+			};
+			PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					20,
+					1053,
+					60,
+					20,
+					48,
+					43,
+					43,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXFileDataSource_FiletypeID,
+					PBXFileDataSource_Filename_ColumnID,
+					PBXTargetDataSource_PrimaryAttribute,
+					PBXFileDataSource_Built_ColumnID,
+					PBXFileDataSource_ObjectSize_ColumnID,
+					PBXFileDataSource_Errors_ColumnID,
+					PBXFileDataSource_Warnings_ColumnID,
+				);
+			};
+			PBXPerProjectTemplateStateSaveDate = 377040721;
+			PBXWorkspaceStateSaveDate = 377040721;
+		};
+		perUserProjectItems = {
+			4F7E1ED716792F8400907FCF /* XCBuildMessageTextBookmark */ = 4F7E1ED716792F8400907FCF /* XCBuildMessageTextBookmark */;
+			4F7E1EDC16792F9100907FCF /* PBXTextBookmark */ = 4F7E1EDC16792F9100907FCF /* PBXTextBookmark */;
+		};
+		sourceControlManager = 4FE33FF310B4519D00B5FB70 /* Source Control */;
+		userBuildSettings = {
+			OBJROOT = "$(SYMROOT)";
+			SYMROOT = "$(PROJECT_DIRECTORY)build-mac";
+		};
+	};
+	4F017360154D4BFC0034BE1A /* AAX_CIPlugParameters.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1216, 1222}}";
+			sepNavSelRange = "{2972, 1}";
+			sepNavVisRange = "{883, 2893}";
+		};
+	};
+	4F017361154D4BFC0034BE1A /* AAX_CIPlugParameters.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 1417}}";
+			sepNavSelRange = "{2080, 0}";
+			sepNavVisRange = "{1161, 1412}";
+		};
+	};
+	4F1F1BE9135B1F60003A5BB2 /* wdlendian.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1052, 3575}}";
+			sepNavSelRange = "{8079, 14}";
+			sepNavVisRange = "{7651, 977}";
+			sepNavWindowFrame = "{{433, 76}, {1089, 914}}";
+		};
+	};
+	4F20EEC8132C69FE0030E34C /* VST2 */ = {
+		activeExec = 0;
+	};
+	4F2BB0CF141402D500564FFC /* Studio One */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 0;
+		comments = "/Applications/Studio One.app";
+		configStateDict = {
+			"PBXLSLaunchAction-0" = {
+				PBXLSLaunchAction = 0;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXLSRunLaunchConfig;
+				commandLineArgs = (
+				);
+				displayName = "Executable Runner";
+				environment = {
+				};
+				identifier = com.apple.Xcode.launch.runConfig;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		launchableReference = 4F2BB0D0141402D500564FFC /* Studio One.app */;
+		libgmallocEnabled = 0;
+		name = "Studio One";
+		savedGlobals = {
+		};
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+		variableFormatDictionary = {
+		};
+	};
+	4F2BB0D0141402D500564FFC /* Studio One.app */ = {
+		isa = PBXFileReference;
+		lastKnownFileType = wrapper.application;
+		name = "Studio One.app";
+		path = "/Applications/Studio One.app";
+		sourceTree = "<absolute>";
+	};
+	4F30A3F21117540400C237CE /* Aulab */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 1;
+		comments = "/Developer/Applications/Audio/AU Lab.app";
+		configStateDict = {
+			"PBXLSLaunchAction-0" = {
+				PBXLSLaunchAction = 0;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXLSRunLaunchConfig;
+				commandLineArgs = (
+				);
+				displayName = "Executable Runner";
+				environment = {
+				};
+				identifier = com.apple.Xcode.launch.runConfig;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		launchableReference = 4F30A3F31117540400C237CE /* AU Lab.app */;
+		libgmallocEnabled = 0;
+		name = Aulab;
+		savedGlobals = {
+		};
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+		startupPath = /Developer/Applications/;
+		variableFormatDictionary = {
+		};
+	};
+	4F30A3F31117540400C237CE /* AU Lab.app */ = {
+		isa = PBXFileReference;
+		lastKnownFileType = wrapper.application;
+		name = "AU Lab.app";
+		path = "Applications/Audio/AU Lab.app";
+		sourceTree = DEVELOPER_DIR;
+	};
+	4F3AE17812C0E5E2001FD7A4 /* AU */ = {
+		activeExec = 0;
+	};
+	4F3E69041409746500C4D749 /* IPlugVST3.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1039, 13559}}";
+			sepNavSelRange = "{18267, 0}";
+			sepNavVisRange = "{0, 1673}";
+		};
+	};
+	4F3E69051409746500C4D749 /* IPlugVST3.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1344, 2119}}";
+			sepNavSelRange = "{3834, 0}";
+			sepNavVisRange = "{2025, 2887}";
+		};
+	};
+	4F3EE94513B65A350097B791 /* IPlugOSDetect.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1200, 947}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 449}";
+		};
+	};
+	4F4ACFF7140996A10068A6D4 /* pluginview.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {671, 1287}}";
+			sepNavSelRange = "{2316, 0}";
+			sepNavVisRange = "{1666, 929}";
+		};
+	};
+	4F4ACFF8140996A10068A6D4 /* pluginview.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 1352}}";
+			sepNavSelRange = "{4276, 24}";
+			sepNavVisRange = "{1091, 3212}";
+		};
+	};
+	4F4ACFFB140996A10068A6D4 /* macmain.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1275, 1144}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{2218, 1170}";
+		};
+	};
+	4F4ACFFC140996A10068A6D4 /* pluginfactoryvst3.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1275, 3172}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2203}";
+		};
+	};
+	4F4ACFFD140996A10068A6D4 /* pluginfactoryvst3.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 2301}}";
+			sepNavSelRange = "{5447, 0}";
+			sepNavVisRange = "{4280, 2667}";
+		};
+	};
+	4F4ACFFF140996A10068A6D4 /* vstaudioeffect.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 2171}}";
+			sepNavSelRange = "{2508, 5}";
+			sepNavVisRange = "{0, 3345}";
+		};
+	};
+	4F4AD000140996A10068A6D4 /* vstaudioeffect.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 1508}}";
+			sepNavSelRange = "{2579, 9}";
+			sepNavVisRange = "{1953, 3170}";
+		};
+	};
+	4F4AD004140996A10068A6D4 /* vstcomponent.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 1560}}";
+			sepNavSelRange = "{2569, 13}";
+			sepNavVisRange = "{2239, 2807}";
+		};
+	};
+	4F4AD005140996A10068A6D4 /* vstcomponentbase.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 2275}}";
+			sepNavSelRange = "{4332, 0}";
+			sepNavVisRange = "{3038, 1907}";
+		};
+	};
+	4F4AD006140996A10068A6D4 /* vstcomponentbase.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 1391}}";
+			sepNavSelRange = "{2589, 11}";
+			sepNavVisRange = "{1757, 2670}";
+		};
+	};
+	4F4AD00C140996A10068A6D4 /* vstparameters.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 5460}}";
+			sepNavSelRange = "{10804, 13}";
+			sepNavVisRange = "{9526, 2148}";
+		};
+	};
+	4F4AD00D140996A10068A6D4 /* vstparameters.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 2912}}";
+			sepNavSelRange = "{8473, 12}";
+			sepNavVisRange = "{6174, 2999}";
+		};
+	};
+	4F4AD012140996A10068A6D4 /* vstsinglecomponenteffect.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1280, 3172}}";
+			sepNavSelRange = "{254, 0}";
+			sepNavVisRange = "{0, 2319}";
+		};
+	};
+	4F4AD013140996A10068A6D4 /* vstsinglecomponenteffect.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 2275}}";
+			sepNavSelRange = "{3190, 48}";
+			sepNavVisRange = "{574, 3744}";
+		};
+	};
+	4F4AD017140996A10068A6D4 /* conststringtable.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1275, 767}}";
+			sepNavSelRange = "{734, 0}";
+			sepNavVisRange = "{0, 2284}";
+		};
+	};
+	4F4AD01B140996A10068A6D4 /* fstrdefs.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1539, 3575}}";
+			sepNavSelRange = "{2834, 0}";
+			sepNavVisRange = "{2629, 448}";
+		};
+	};
+	4F4AD01C140996A10068A6D4 /* ftypes.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 2275}}";
+			sepNavSelRange = "{2113, 19}";
+			sepNavVisRange = "{0, 2693}";
+		};
+	};
+	4F4AD01E140996A10068A6D4 /* funknown.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 8580}}";
+			sepNavSelRange = "{17455, 0}";
+			sepNavVisRange = "{16051, 2077}";
+		};
+	};
+	4F4AD020140996A10068A6D4 /* ibstream.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 1131}}";
+			sepNavSelRange = "{2548, 0}";
+			sepNavVisRange = "{0, 3643}";
+		};
+	};
+	4F4AD024140996A10068A6D4 /* ipluginbase.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 5278}}";
+			sepNavSelRange = "{2709, 35}";
+			sepNavVisRange = "{0, 3778}";
+		};
+	};
+	4F4AD02B140996A10068A6D4 /* iplugview.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {936, 2496}}";
+			sepNavSelRange = "{5343, 0}";
+			sepNavVisRange = "{4718, 1544}";
+		};
+	};
+	4F4AD02E140996A10068A6D4 /* ivstaudioprocessor.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 3965}}";
+			sepNavSelRange = "{11393, 14}";
+			sepNavVisRange = "{9333, 4065}";
+		};
+	};
+	4F4AD02F140996A10068A6D4 /* ivstcomponent.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 2834}}";
+			sepNavSelRange = "{7858, 1}";
+			sepNavVisRange = "{5756, 3654}";
+		};
+	};
+	4F4AD030140996A10068A6D4 /* ivstcontextmenu.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1861, 3094}}";
+			sepNavSelRange = "{6200, 0}";
+			sepNavVisRange = "{4455, 2268}";
+		};
+	};
+	4F4AD031140996A10068A6D4 /* ivsteditcontroller.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1861, 5343}}";
+			sepNavSelRange = "{6881, 0}";
+			sepNavVisRange = "{4856, 3092}";
+		};
+	};
+	4F4AD032140996A10068A6D4 /* ivstevents.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 2249}}";
+			sepNavSelRange = "{2564, 7}";
+			sepNavVisRange = "{1480, 3142}";
+		};
+	};
+	4F4AD034140996A10068A6D4 /* ivstmessage.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 1534}}";
+			sepNavSelRange = "{3285, 0}";
+			sepNavVisRange = "{759, 3326}";
+		};
+	};
+	4F4AD038140996A10068A6D4 /* ivstplugview.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {727, 1027}}";
+			sepNavSelRange = "{2742, 8}";
+			sepNavVisRange = "{2056, 1364}";
+		};
+	};
+	4F4AD039140996A10068A6D4 /* ivstprocesscontext.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 2145}}";
+			sepNavSelRange = "{2046, 0}";
+			sepNavVisRange = "{0, 3527}";
+		};
+	};
+	4F4AD03E140996A10068A6D4 /* vsttypes.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1606, 7371}}";
+			sepNavSelRange = "{4236, 67}";
+			sepNavVisRange = "{2754, 3404}";
+		};
+	};
+	4F4AD1B61409A2BB0068A6D4 /* VST3TestHost */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 1;
+		configStateDict = {
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		launchableReference = 4F4AD1B71409A2BB0068A6D4 /* VST3PluginTestHost.app */;
+		libgmallocEnabled = 0;
+		name = VST3TestHost;
+		savedGlobals = {
+		};
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+		variableFormatDictionary = {
+		};
+	};
+	4F4AD1B71409A2BB0068A6D4 /* VST3PluginTestHost.app */ = {
+		isa = PBXFileReference;
+		lastKnownFileType = wrapper.application;
+		name = VST3PluginTestHost.app;
+		path = /Applications/VST3PluginTestHost.app;
+		sourceTree = "<absolute>";
+	};
+	4F4CC38A1549B91100A9EA21 /* AAX_Exports.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1200, 2054}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2051}";
+		};
+	};
+	4F4CC38C1549B92900A9EA21 /* CommonDebugSettings.xcconfig */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {2700, 702}}";
+			sepNavSelRange = "{679, 0}";
+			sepNavVisRange = "{0, 2161}";
+		};
+	};
+	4F4CC38D1549B92900A9EA21 /* CommonReleaseSettings.xcconfig */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {2693, 871}}";
+			sepNavSelRange = "{1326, 0}";
+			sepNavVisRange = "{570, 2040}";
+		};
+	};
+	4F4CC4251549BED600A9EA21 /* IPlugAAX.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1344, 7657}}";
+			sepNavSelRange = "{12918, 0}";
+			sepNavVisRange = "{12127, 1201}";
+		};
+	};
+	4F4CC4261549BED600A9EA21 /* IPlugAAX.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {810, 1404}}";
+			sepNavSelRange = "{351, 0}";
+			sepNavVisRange = "{19, 921}";
+		};
+	};
+	4F4CC4401549C15500A9EA21 /* IPlugAAX_Describe.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 2106}}";
+			sepNavSelRange = "{3057, 0}";
+			sepNavVisRange = "{2346, 1972}";
+		};
+	};
+	4F4F73791576739300C124E3 /* AAX_CIPlugTaperDelegate.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 1248}}";
+			sepNavSelRange = "{1006, 51}";
+			sepNavVisRange = "{128, 1278}";
+		};
+	};
+	4F647528132A790E00D7E58C /* Auval */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+			YES,
+		);
+		argumentStrings = (
+			"-v aufx Ipef Acme",
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 1;
+		comments = "remember to change executable arguments to match plugin's type and IDs: aufx/aumf/aumu PLUG_UNIQUE_ID PLUG_MFR_ID";
+		configStateDict = {
+			"PBXLSLaunchAction-0" = {
+				PBXLSLaunchAction = 0;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXLSRunLaunchConfig;
+				commandLineArgs = (
+				);
+				displayName = "Executable Runner";
+				environment = {
+				};
+				identifier = com.apple.Xcode.launch.runConfig;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		launchableReference = 4F647529132A790E00D7E58C /* arch -i386 -ppc */;
+		libgmallocEnabled = 0;
+		name = Auval;
+		savedGlobals = {
+		};
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+		startupPath = "<<ProjectDirectory>>";
+		variableFormatDictionary = {
+		};
+	};
+	4F647529132A790E00D7E58C /* arch -i386 -ppc */ = {
+		isa = PBXFileReference;
+		lastKnownFileType = "compiled.mach-o.executable";
+		name = "arch -i386 -ppc";
+		path = /usr/bin/auvaltool;
+		sourceTree = "<absolute>";
+	};
+	4F78D89613B639100032E0F3 /* English */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1095, 739}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 92}";
+		};
+	};
+	4F78D8BD13B63A4E0032E0F3 /* wdltypes.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1344, 949}}";
+			sepNavSelRange = "{1266, 0}";
+			sepNavVisRange = "{0, 1251}";
+		};
+	};
+	4F78D8BF13B63A700032E0F3 /* RtAudio.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1188, 103454}}";
+			sepNavSelRange = "{40356, 0}";
+			sepNavVisRange = "{39137, 3440}";
+		};
+	};
+	4F78D8C013B63A700032E0F3 /* RtAudio.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1177, 13000}}";
+			sepNavSelRange = "{33765, 284}";
+			sepNavVisRange = "{33449, 1980}";
+		};
+	};
+	4F78D8C113B63A700032E0F3 /* RtError.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1177, 793}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2129}";
+		};
+	};
+	4F78D8C213B63A700032E0F3 /* RtMidi.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1315, 36218}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2106}";
+		};
+	};
+	4F78D8C313B63A700032E0F3 /* RtMidi.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1511, 3874}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2350}";
+		};
+	};
+	4F78D8D213B63B5D0032E0F3 /* aeffect.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1155, 4849}}";
+			sepNavSelRange = "{3076, 368}";
+			sepNavVisRange = "{2160, 3306}";
+		};
+	};
+	4F78D8D313B63B5D0032E0F3 /* aeffectx.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1155, 15444}}";
+			sepNavSelRange = "{55719, 0}";
+			sepNavVisRange = "{54038, 2044}";
+		};
+	};
+	4F78D8E613B63BA40032E0F3 /* IPlug_include_in_plug_hdr.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 767}}";
+			sepNavSelRange = "{709, 0}";
+			sepNavVisRange = "{445, 1010}";
+		};
+	};
+	4F78D8E813B63BA40032E0F3 /* IPlug_include_in_plug_src.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 2938}}";
+			sepNavSelRange = "{436, 0}";
+			sepNavVisRange = "{56, 1006}";
+		};
+	};
+	4F78D8E913B63BA40032E0F3 /* IControl.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1344, 5174}}";
+			sepNavSelRange = "{3825, 37}";
+			sepNavVisRange = "{2716, 2118}";
+		};
+	};
+	4F78D8EA13B63BA40032E0F3 /* IKeyboardControl.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 3861}}";
+			sepNavSelRange = "{4621, 0}";
+			sepNavVisRange = "{3973, 1189}";
+		};
+	};
+	4F78D8EB13B63BA40032E0F3 /* IPlugStandalone.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 2002}}";
+			sepNavSelRange = "{2048, 0}";
+			sepNavVisRange = "{1785, 739}";
+		};
+	};
+	4F78D8EC13B63BA40032E0F3 /* IPlugBase.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1158, 4251}}";
+			sepNavSelRange = "{2507, 0}";
+			sepNavVisRange = "{1710, 3543}";
+			sepNavWindowFrame = "{{15, 113}, {1416, 1060}}";
+		};
+	};
+	4F78D8ED13B63BA40032E0F3 /* IPlugBase.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1039, 19695}}";
+			sepNavSelRange = "{12014, 0}";
+			sepNavVisRange = "{11187, 1309}";
+		};
+	};
+	4F78D8EE13B63BA50032E0F3 /* IGraphicsMac.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1539, 2210}}";
+			sepNavSelRange = "{1749, 0}";
+			sepNavVisRange = "{1561, 613}";
+		};
+	};
+	4F78D8EF13B63BA50032E0F3 /* IPlugStructs.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 1755}}";
+			sepNavSelRange = "{685, 0}";
+			sepNavVisRange = "{0, 986}";
+		};
+	};
+	4F78D8F113B63BA50032E0F3 /* Containers.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 3822}}";
+			sepNavSelRange = "{2186, 0}";
+			sepNavVisRange = "{1220, 1086}";
+		};
+	};
+	4F78D8F213B63BA50032E0F3 /* Hosts.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 754}}";
+			sepNavSelRange = "{98, 89}";
+			sepNavVisRange = "{0, 794}";
+		};
+	};
+	4F78D8F313B63BA50032E0F3 /* Hosts.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 1547}}";
+			sepNavSelRange = "{378, 0}";
+			sepNavVisRange = "{0, 1765}";
+		};
+	};
+	4F78D8F513B63BA50032E0F3 /* IGraphicsMac.mm */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1052, 7839}}";
+			sepNavSelRange = "{9319, 9}";
+			sepNavVisRange = "{9029, 498}";
+		};
+	};
+	4F78D8F613B63BA50032E0F3 /* IGraphics.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1344, 15145}}";
+			sepNavSelRange = "{6372, 82}";
+			sepNavVisRange = "{5821, 1202}";
+		};
+	};
+	4F78D8F713B63BA50032E0F3 /* IGraphicsCarbon.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 9620}}";
+			sepNavSelRange = "{21536, 0}";
+			sepNavVisRange = "{20977, 1462}";
+		};
+	};
+	4F78D8F813B63BA50032E0F3 /* IGraphicsCocoa.mm */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 7709}}";
+			sepNavSelRange = "{6955, 0}";
+			sepNavVisRange = "{6003, 1435}";
+		};
+	};
+	4F78D8F913B63BA50032E0F3 /* IGraphicsCocoa.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {976, 975}}";
+			sepNavSelRange = "{1249, 21}";
+			sepNavVisRange = "{468, 1946}";
+		};
+	};
+	4F78D8FA13B63BA50032E0F3 /* Log.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 845}}";
+			sepNavSelRange = "{852, 39}";
+			sepNavVisRange = "{143, 1332}";
+		};
+	};
+	4F78D8FB13B63BA50032E0F3 /* Log.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 8060}}";
+			sepNavSelRange = "{94, 0}";
+			sepNavVisRange = "{0, 941}";
+		};
+	};
+	4F78D8FC13B63BA50032E0F3 /* IPopupMenu.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 1014}}";
+			sepNavSelRange = "{1105, 0}";
+			sepNavVisRange = "{537, 1581}";
+		};
+	};
+	4F78D8FD13B63BA50032E0F3 /* IPopupMenu.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1095, 1430}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 914}";
+		};
+	};
+	4F78D8FE13B63BA50032E0F3 /* IPlugStructs.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1344, 5421}}";
+			sepNavSelRange = "{2611, 0}";
+			sepNavVisRange = "{47, 1797}";
+		};
+	};
+	4F78D90213B63BA50032E0F3 /* IPlug_Prefix.pch */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1539, 399}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 142}";
+		};
+	};
+	4F78D90313B63BA50032E0F3 /* IParam.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1039, 1183}}";
+			sepNavSelRange = "{1075, 0}";
+			sepNavVisRange = "{453, 2374}";
+		};
+	};
+	4F78D90413B63BA50032E0F3 /* IParam.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1039, 2678}}";
+			sepNavSelRange = "{259, 12}";
+			sepNavVisRange = "{3470, 922}";
+		};
+	};
+	4F78D90513B63BA50032E0F3 /* IMidiQueue.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {880, 2691}}";
+			sepNavSelRange = "{1978, 0}";
+			sepNavVisRange = "{1504, 655}";
+		};
+	};
+	4F78D90713B63BA50032E0F3 /* IGraphicsCarbon.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {904, 859}}";
+			sepNavSelRange = "{1576, 0}";
+			sepNavVisRange = "{0, 1576}";
+		};
+	};
+	4F78D90813B63BA50032E0F3 /* IGraphics.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1539, 3250}}";
+			sepNavSelRange = "{5572, 0}";
+			sepNavVisRange = "{5140, 886}";
+		};
+	};
+	4F78D90913B63BA50032E0F3 /* IControl.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1861, 7982}}";
+			sepNavSelRange = "{188, 0}";
+			sepNavVisRange = "{0, 1050}";
+		};
+	};
+	4F78D9EA13B63BE90032E0F3 /* IPlugStandalone.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1275, 1339}}";
+			sepNavSelRange = "{2038, 556}";
+			sepNavVisRange = "{1409, 1193}";
+		};
+	};
+	4F78D9EC13B63C6A0032E0F3 /* IPlugVST.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 11687}}";
+			sepNavSelRange = "{1063, 0}";
+			sepNavVisRange = "{18612, 1447}";
+		};
+	};
+	4F78D9ED13B63C6A0032E0F3 /* IPlugVST.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1200, 1274}}";
+			sepNavSelRange = "{1982, 17}";
+			sepNavVisRange = "{0, 1976}";
+		};
+	};
+	4F78D9FB13B63CD90032E0F3 /* IPlugAU.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1271, 2691}}";
+			sepNavSelRange = "{6896, 0}";
+			sepNavVisRange = "{0, 1529}";
+		};
+	};
+	4F78D9FC13B63CD90032E0F3 /* IPlugAU.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1271, 28327}}";
+			sepNavSelRange = "{84, 0}";
+			sepNavVisRange = "{0, 1283}";
+		};
+	};
+	4F78D9FD13B63CD90032E0F3 /* IPlugAU.r */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1097, 2548}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 1726}";
+		};
+	};
+	4F78D9FE13B63CD90032E0F3 /* IPlugAU_ViewFactory.mm */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1097, 672}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 945}";
+		};
+	};
+	4F78DAEA13B642790032E0F3 /* IGraphicsWin.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 13351}}";
+			sepNavSelRange = "{12340, 0}";
+			sepNavVisRange = "{11572, 1365}";
+		};
+	};
+	4F78DAEB13B642790032E0F3 /* IGraphicsWin.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1155, 980}}";
+			sepNavSelRange = "{1726, 13}";
+			sepNavVisRange = "{0, 2169}";
+		};
+	};
+	4F78DAF113B643600032E0F3 /* All */ = {
+		activeExec = 0;
+	};
+	4F79A34C146304CD00744AED /* IPlugProcessAS.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 2405}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{4386, 1112}";
+		};
+	};
+	4F79A34D146304CD00744AED /* IPlugProcessAS.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1095, 732}}";
+			sepNavSelRange = "{1135, 0}";
+			sepNavVisRange = "{0, 1476}";
+		};
+	};
+	4F7E1ED716792F8400907FCF /* XCBuildMessageTextBookmark */ = {
+		isa = PBXTextBookmark;
+		comments = "'NSView' may not respond to '-_recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:'";
+		fRef = 4FD16D0413B634AA001D0217 /* swell-dlg.mm */;
+		fallbackIsa = XCBuildMessageTextBookmark;
+		rLen = 1;
+		rLoc = 1059;
+		rType = 1;
+	};
+	4F7E1EDC16792F9100907FCF /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = 4FD16D0413B634AA001D0217 /* swell-dlg.mm */;
+		name = "swell-dlg.mm: 1064";
+		rLen = 0;
+		rLoc = 34197;
+		rType = 0;
+		vrLen = 809;
+		vrLoc = 33777;
+	};
+	4F7F5C4213E95EC8002918FD /* RTAS */ = {
+		activeExec = 0;
+	};
+	4F7F5C6F13E95FB2002918FD /* IPlugRTAS.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1344, 3341}}";
+			sepNavSelRange = "{3625, 0}";
+			sepNavVisRange = "{3382, 1426}";
+		};
+	};
+	4F7F5C7013E95FB2002918FD /* IPlugRTAS.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1344, 949}}";
+			sepNavSelRange = "{955, 0}";
+			sepNavVisRange = "{186, 1735}";
+		};
+	};
+	4F7F5C9B13E9607A002918FD /* digicode.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1301, 650}}";
+			sepNavSelRange = "{854, 0}";
+			sepNavVisRange = "{380, 923}";
+		};
+	};
+	4F7F5C9C13E9607A002918FD /* digicode1.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1539, 487}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 349}";
+		};
+	};
+	4F7F5C9F13E9607A002918FD /* EditorInterface.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1095, 728}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 888}";
+		};
+	};
+	4F7F5CA013E9607A002918FD /* IPlugCustomUI.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 4030}}";
+			sepNavSelRange = "{7751, 0}";
+			sepNavVisRange = "{6781, 977}";
+		};
+	};
+	4F7F5CA113E9607A002918FD /* IPlugCustomUI.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 1066}}";
+			sepNavSelRange = "{189, 0}";
+			sepNavVisRange = "{0, 1428}";
+		};
+	};
+	4F7F5CA213E9607A002918FD /* IPlugDigiView.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1095, 603}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 659}";
+		};
+	};
+	4F7F5CA313E9607A002918FD /* IPlugGroup.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1111, 2431}}";
+			sepNavSelRange = "{2431, 2813}";
+			sepNavVisRange = "{3492, 1898}";
+		};
+	};
+	4F7F5CA413E9607A002918FD /* IPlugGroup.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1095, 603}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 305}";
+		};
+	};
+	4F7F5CA513E9607A002918FD /* IPlugProcess.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1344, 6266}}";
+			sepNavSelRange = "{1668, 0}";
+			sepNavVisRange = "{1021, 1632}";
+		};
+	};
+	4F7F5CA613E9607A002918FD /* IPlugProcess.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1039, 1313}}";
+			sepNavSelRange = "{2307, 0}";
+			sepNavVisRange = "{0, 2180}";
+		};
+	};
+	4F7F5CA713E9607A002918FD /* IPlugProcessRTAS.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 2587}}";
+			sepNavSelRange = "{706, 0}";
+			sepNavVisRange = "{0, 1190}";
+		};
+	};
+	4F7F5CA813E9607A002918FD /* IPlugProcessRTAS.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1097, 712}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 1580}";
+		};
+	};
+	4F7F5CAA13E9607A002918FD /* ProcessInterface.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 661}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 801}";
+		};
+	};
+	4F7F5CAB13E9607A002918FD /* CommonDebugSettings.xcconfig */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {12185, 793}}";
+			sepNavSelRange = "{29, 10}";
+			sepNavVisRange = "{0, 4000}";
+		};
+	};
+	4F7F5CAC13E9607A002918FD /* CommonReleaseSettings.xcconfig */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {12185, 845}}";
+			sepNavSelRange = "{2128, 0}";
+			sepNavVisRange = "{0, 3887}";
+		};
+	};
+	4F7F5D0713E9676F002918FD /* ProTools Dev */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 1;
+		comments = "can be PT9Dev, 10Dev, whatever, install here /Applications/AVID/ProTools_3PDev/Pro Tools.app";
+		configStateDict = {
+			"PBXLSLaunchAction-0" = {
+				PBXLSLaunchAction = 0;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXLSRunLaunchConfig;
+				commandLineArgs = (
+				);
+				displayName = "Executable Runner";
+				environment = {
+				};
+				identifier = com.apple.Xcode.launch.runConfig;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		launchableReference = 4F7F5D0813E9676F002918FD /* Pro Tools.app */;
+		libgmallocEnabled = 0;
+		name = "ProTools Dev";
+		savedGlobals = {
+		};
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+		startupPath = "/Applications/AVID/ProTools_3PDev/Pro Tools.app";
+		variableFormatDictionary = {
+		};
+	};
+	4F7F5D0813E9676F002918FD /* Pro Tools.app */ = {
+		isa = PBXFileReference;
+		lastKnownFileType = folder;
+		name = "Pro Tools.app";
+		path = "/Applications/AVID/ProTools_3PDev/Pro Tools.app";
+		sourceTree = "<absolute>";
+	};
+	4F7F5D2413E9681E002918FD /* IPlugRTAS.r */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1095, 728}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 0}";
+		};
+	};
+	4F8F27C7131A78AE007A37CF /* Garageband */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 0;
+		configStateDict = {
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		launchableReference = 4F8F27C8131A78AE007A37CF /* GarageBand.app */;
+		libgmallocEnabled = 0;
+		name = Garageband;
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+	};
+	4F8F27C8131A78AE007A37CF /* GarageBand.app */ = {
+		isa = PBXFileReference;
+		lastKnownFileType = wrapper.application;
+		name = GarageBand.app;
+		path = /Applications/GarageBand.app;
+		sourceTree = "<absolute>";
+	};
+	4F94D77514EFB6B100DBF4C9 /* Logic */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 0;
+		configStateDict = {
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		launchableReference = 4F94D77614EFB6B100DBF4C9 /* Logic Pro.app */;
+		libgmallocEnabled = 0;
+		name = Logic;
+		savedGlobals = {
+		};
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+		startupPath = "<<ProjectDirectory>>";
+	};
+	4F94D77614EFB6B100DBF4C9 /* Logic Pro.app */ = {
+		isa = PBXFileReference;
+		lastKnownFileType = wrapper.application;
+		name = "Logic Pro.app";
+		path = "/Applications/Logic Pro.app";
+		sourceTree = "<absolute>";
+	};
+	4F94D78014EFB6F800DBF4C9 /* VST3validator */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+			YES,
+		);
+		argumentStrings = (
+			AccessiblePeakMeter.vst3,
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 0;
+		comments = "comes with the VST3 sdk, install in /usr/local/bin/vstvalidator. Remember to change arguments to match pluginname.vst3";
+		configStateDict = {
+			"PBXLSLaunchAction-0" = {
+				PBXLSLaunchAction = 0;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXLSRunLaunchConfig;
+				commandLineArgs = (
+				);
+				displayName = "Executable Runner";
+				environment = {
+				};
+				identifier = com.apple.Xcode.launch.runConfig;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		launchableReference = 4F94D78114EFB6F800DBF4C9 /* vstvalidator */;
+		libgmallocEnabled = 0;
+		name = VST3validator;
+		savedGlobals = {
+		};
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+		startupPath = "<<ProductDirectory>>";
+	};
+	4F94D78114EFB6F800DBF4C9 /* vstvalidator */ = {
+		isa = PBXFileReference;
+		lastKnownFileType = "compiled.mach-o.executable";
+		name = vstvalidator;
+		path = /usr/local/bin/vstvalidator;
+		sourceTree = "<absolute>";
+	};
+	4F9828AA140A9EB700F3FCC1 /* VST3 */ = {
+		activeExec = 0;
+	};
+	4FA88B901444E4C4006CB8DA /* dfx-au-utilities.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1539, 2847}}";
+			sepNavSelRange = "{1504, 0}";
+			sepNavVisRange = "{880, 1364}";
+		};
+	};
+	4FA88B911444E4C4006CB8DA /* dfx-au-utilities.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1271, 910}}";
+			sepNavSelRange = "{1372, 0}";
+			sepNavVisRange = "{740, 1761}";
+		};
+	};
+	4FB3624E13B648FE00DB6B76 /* main.mm */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1271, 655}}";
+			sepNavSelRange = "{119, 0}";
+			sepNavVisRange = "{0, 119}";
+		};
+	};
+	4FB600121567CB0A0020189A /* AAX */ = {
+		activeExec = 0;
+	};
+	4FCF15AF133124D1009A6277 /* AccessiblePeakMeter.xcconfig */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1271, 819}}";
+			sepNavSelRange = "{686, 0}";
+			sepNavVisRange = "{0, 1309}";
+			sepNavWindowFrame = "{{15, 10}, {1135, 1163}}";
+		};
+	};
+	4FD16A0813B63081001D0217 /* APP */ = {
+		activeExec = 0;
+		executables = (
+			4FD16A0A13B63081001D0217 /* APP */,
+		);
+	};
+	4FD16A0A13B63081001D0217 /* APP */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 1;
+		configStateDict = {
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		libgmallocEnabled = 0;
+		name = APP;
+		savedGlobals = {
+		};
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+		variableFormatDictionary = {
+		};
+	};
+	4FD16C9E13B6327C001D0217 /* app_resource.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 559}}";
+			sepNavSelRange = "{1124, 0}";
+			sepNavVisRange = "{0, 1249}";
+		};
+	};
+	4FD16C9F13B6327C001D0217 /* app_main.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1271, 2041}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 1255}";
+		};
+	};
+	4FD16CA013B6327C001D0217 /* app_main.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 13507}}";
+			sepNavSelRange = "{339, 0}";
+			sepNavVisRange = "{0, 902}";
+		};
+	};
+	4FD16CA113B6327C001D0217 /* app_dialog.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 7527}}";
+			sepNavSelRange = "{18281, 0}";
+			sepNavVisRange = "{18073, 1143}";
+		};
+	};
+	4FD16CFB13B63468001D0217 /* swell-appstub.mm */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1216, 810}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 1115}";
+		};
+	};
+	4FD16D0213B63489001D0217 /* swell-menugen.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1216, 1300}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 1766}";
+		};
+	};
+	4FD16D0313B63494001D0217 /* swell-dlggen.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1621, 3744}}";
+			sepNavSelRange = "{2998, 14}";
+			sepNavVisRange = "{1745, 2153}";
+		};
+	};
+	4FD16D0413B634AA001D0217 /* swell-dlg.mm */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1202, 41093}}";
+			sepNavSelRange = "{34023, 0}";
+			sepNavVisRange = "{33777, 540}";
+		};
+	};
+	4FD16D0B13B634BF001D0217 /* swell-gdi.mm */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1230, 18772}}";
+			sepNavSelRange = "{12603, 24}";
+			sepNavVisRange = "{12418, 464}";
+		};
+	};
+	4FD16D1513B634D2001D0217 /* swell-ini.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1216, 6370}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2168}";
+		};
+	};
+	4FD16D1713B634E5001D0217 /* swell.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1511, 2054}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 1987}";
+		};
+	};
+	4FD16D2213B6351C001D0217 /* swell-functions.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1200, 13936}}";
+			sepNavSelRange = "{5001, 67}";
+			sepNavVisRange = "{3965, 2209}";
+		};
+	};
+	4FD16D2B13B6353C001D0217 /* swell-internal.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1216, 8710}}";
+			sepNavSelRange = "{172, 0}";
+			sepNavVisRange = "{0, 2070}";
+		};
+	};
+	4FD16D3013B6355A001D0217 /* swell-types.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1539, 17342}}";
+			sepNavSelRange = "{2398, 1}";
+			sepNavVisRange = "{1784, 714}";
+		};
+	};
+	4FD16D3913B63582001D0217 /* swell-kb.mm */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {3309, 7943}}";
+			sepNavSelRange = "{3207, 34}";
+			sepNavVisRange = "{2588, 1680}";
+		};
+	};
+	4FD16D3B13B6358C001D0217 /* swell-miscdlg.mm */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1216, 4381}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2054}";
+		};
+	};
+	4FD16D3D13B63595001D0217 /* swell-menu.mm */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1216, 11167}}";
+			sepNavSelRange = "{18733, 38}";
+			sepNavVisRange = "{9043, 1395}";
+		};
+	};
+	4FD16D3F13B635A0001D0217 /* swell-misc.mm */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1200, 7449}}";
+			sepNavSelRange = "{1077, 47}";
+			sepNavVisRange = "{566, 1248}";
+		};
+	};
+	4FD16D4113B635AB001D0217 /* swell-wnd.mm */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1200, 71136}}";
+			sepNavSelRange = "{1756, 67}";
+			sepNavVisRange = "{3973, 997}";
+		};
+	};
+	4FD16D4313B635B2001D0217 /* swell.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1511, 11544}}";
+			sepNavSelRange = "{1039, 0}";
+			sepNavVisRange = "{0, 1619}";
+		};
+	};
+	4FD16D4513B635C8001D0217 /* swellappmain.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1216, 760}}";
+			sepNavSelRange = "{37, 16}";
+			sepNavVisRange = "{0, 210}";
+		};
+	};
+	4FD16D4613B635C8001D0217 /* swellappmain.mm */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1539, 3055}}";
+			sepNavSelRange = "{822, 7}";
+			sepNavVisRange = "{0, 1434}";
+		};
+	};
+	4FD290A8137C34D700CEBE7E /* AccessiblePeakMeter.icns */ = {
+		uiCtxt = {
+			sepNavWindowFrame = "{{38, 92}, {1416, 1060}}";
+		};
+	};
+	4FDA440513F3E4F2000B4551 /* IBitmapMonoText.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 1261}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{565, 970}";
+		};
+	};
+	4FDA440613F3E4F2000B4551 /* IBitmapMonoText.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 624}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 1048}";
+		};
+	};
+	4FE33FF310B4519D00B5FB70 /* Source Control */ = {
+		isa = PBXSourceControlManager;
+		fallbackIsa = XCSourceControlManager;
+		isSCMEnabled = 0;
+		scmConfiguration = {
+			repositoryNamesForRoots = {
+				"" = "";
+			};
+		};
+	};
+	4FE33FF410B4519D00B5FB70 /* Code sense */ = {
+		isa = PBXCodeSenseManager;
+		indexTemplatePath = "";
+	};
+	4FF016F4134E14E2001447BA /* mutex.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1301, 3133}}";
+			sepNavSelRange = "{3873, 0}";
+			sepNavVisRange = "{3435, 914}";
+		};
+	};
+	4FF016F5134E14E2001447BA /* ptrlist.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {936, 2314}}";
+			sepNavSelRange = "{1807, 0}";
+			sepNavVisRange = "{1499, 745}";
+		};
+	};
+	4FF016F6134E14E2001447BA /* wdlstring.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 4472}}";
+			sepNavSelRange = "{1222, 0}";
+			sepNavVisRange = "{0, 1448}";
+		};
+	};
+	4FF01719134E153A001447BA /* heapbuf.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1621, 4537}}";
+			sepNavSelRange = "{8520, 0}";
+			sepNavVisRange = "{6893, 1858}";
+		};
+	};
+	4FF2407313FAB21200E40631 /* AudioMulch */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 0;
+		comments = "install here /Applications/AudioMulch/AudioMulch.app";
+		configStateDict = {
+			"PBXLSLaunchAction-0" = {
+				PBXLSLaunchAction = 0;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXLSRunLaunchConfig;
+				commandLineArgs = (
+				);
+				displayName = "Executable Runner";
+				environment = {
+				};
+				identifier = com.apple.Xcode.launch.runConfig;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		launchableReference = 4FF2407413FAB21200E40631 /* AudioMulch.app */;
+		libgmallocEnabled = 0;
+		name = AudioMulch;
+		savedGlobals = {
+		};
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+	};
+	4FF2407413FAB21200E40631 /* AudioMulch.app */ = {
+		isa = PBXFileReference;
+		lastKnownFileType = wrapper.application;
+		name = AudioMulch.app;
+		path = /Applications/AudioMulch/AudioMulch.app;
+		sourceTree = "<absolute>";
+	};
+	4FF6D80B12B285AF001E9114 /* Cubase */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 1;
+		comments = "Cubase 6";
+		configStateDict = {
+			"PBXLSLaunchAction-0" = {
+				PBXLSLaunchAction = 0;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXLSRunLaunchConfig;
+				commandLineArgs = (
+				);
+				displayName = "Executable Runner";
+				environment = {
+				};
+				identifier = com.apple.Xcode.launch.runConfig;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		launchableReference = 4FF6D80C12B285AF001E9114 /* Cubase 6.app */;
+		libgmallocEnabled = 0;
+		name = Cubase;
+		savedGlobals = {
+		};
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+		startupPath = /Applications/;
+		variableFormatDictionary = {
+		};
+	};
+	4FF6D80C12B285AF001E9114 /* Cubase 6.app */ = {
+		isa = PBXFileReference;
+		lastKnownFileType = wrapper.application;
+		name = "Cubase 6.app";
+		path = "/Applications/Cubase 6.app";
+		sourceTree = "<absolute>";
+	};
+	4FF6D80D12B285DC001E9114 /* Reaper */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 1;
+		comments = /Applications/REAPER.app;
+		configStateDict = {
+			"PBXLSLaunchAction-0" = {
+				PBXLSLaunchAction = 0;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXLSRunLaunchConfig;
+				commandLineArgs = (
+				);
+				displayName = "Executable Runner";
+				environment = {
+				};
+				identifier = com.apple.Xcode.launch.runConfig;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		launchableReference = 4FF6D80E12B285DC001E9114 /* REAPER.app */;
+		libgmallocEnabled = 0;
+		name = Reaper;
+		savedGlobals = {
+		};
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+		startupPath = /Applications/;
+		variableFormatDictionary = {
+		};
+	};
+	4FF6D80E12B285DC001E9114 /* REAPER.app */ = {
+		isa = PBXFileReference;
+		lastKnownFileType = wrapper.application;
+		name = REAPER.app;
+		path = /Applications/REAPER.app;
+		sourceTree = "<absolute>";
+	};
+	4FF6D80F12B28631001E9114 /* Live */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 1;
+		comments = /Applications/Live/Live.app;
+		configStateDict = {
+			"PBXLSLaunchAction-0" = {
+				PBXLSLaunchAction = 0;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXLSRunLaunchConfig;
+				commandLineArgs = (
+				);
+				displayName = "Executable Runner";
+				environment = {
+				};
+				identifier = com.apple.Xcode.launch.runConfig;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		launchableReference = 4FF6D81012B28631001E9114 /* Live.app */;
+		libgmallocEnabled = 0;
+		name = Live;
+		savedGlobals = {
+		};
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+		startupPath = /Applications/;
+		variableFormatDictionary = {
+		};
+	};
+	4FF6D81012B28631001E9114 /* Live.app */ = {
+		isa = PBXFileReference;
+		lastKnownFileType = wrapper.application;
+		name = Live.app;
+		path = /Applications/Live/Live.app;
+		sourceTree = "<absolute>";
+	};
+	4FF7B0D4156A825000E6CB12 /* common.xcconfig */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1335, 647}}";
+			sepNavSelRange = "{302, 0}";
+			sepNavVisRange = "{0, 2094}";
+		};
+	};
+	526F9C010D7DC7D700562CF8 /* AccessiblePeakMeter.exp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1120, 501}}";
+			sepNavSelRange = "{38, 0}";
+			sepNavVisRange = "{0, 42}";
+		};
+	};
+	52FBBED00D0CF139001C8B8A /* AccessiblePeakMeter.cpp */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1271, 1014}}";
+			sepNavSelRange = "{409, 1}";
+			sepNavVisRange = "{0, 1148}";
+			sepNavWindowFrame = "{{15, 109}, {1089, 914}}";
+		};
+	};
+	52FBBED20D0CF13D001C8B8A /* AccessiblePeakMeter.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1271, 644}}";
+			sepNavSelRange = "{329, 0}";
+			sepNavVisRange = "{0, 366}";
+		};
+	};
+	52FBBED30D0CF143001C8B8A /* resource.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1271, 1092}}";
+			sepNavSelRange = "{160, 0}";
+			sepNavVisRange = "{0, 1439}";
+			sepNavWindowFrame = "{{15, 4}, {1416, 1024}}";
+		};
+	};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter.xcodeproj/project.pbxproj	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,2893 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXAggregateTarget section */
+		4F78DAF113B643600032E0F3 /* All */ = {
+			isa = PBXAggregateTarget;
+			buildConfigurationList = 4F78DAFD13B643940032E0F3 /* Build configuration list for PBXAggregateTarget "All" */;
+			buildPhases = (
+			);
+			dependencies = (
+				4F78DAF613B6436B0032E0F3 /* PBXTargetDependency */,
+				4F78DAF813B6436B0032E0F3 /* PBXTargetDependency */,
+				4F78DAFA13B6436B0032E0F3 /* PBXTargetDependency */,
+				4F8D4C6313E97B3D004F7633 /* PBXTargetDependency */,
+				4F9828F8140A9F0200F3FCC1 /* PBXTargetDependency */,
+				4F789ED016763E47009EF688 /* PBXTargetDependency */,
+			);
+			name = All;
+			productName = "AllOSX_32&64_intel";
+		};
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+		4F1F1BEA135B1F60003A5BB2 /* wdlendian.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F1F1BE9135B1F60003A5BB2 /* wdlendian.h */; };
+		4F20EECB132C69FE0030E34C /* AccessiblePeakMeter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBED00D0CF139001C8B8A /* AccessiblePeakMeter.cpp */; };
+		4F20EF2D132C69FE0030E34C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
+		4F20EF2E132C69FE0030E34C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52C4DB180D0E51270007A920 /* Carbon.framework */; };
+		4F23B9F313B647A00097A67E /* knob.png in Resources */ = {isa = PBXBuildFile; fileRef = 4F23B9E413B647A00097A67E /* knob.png */; };
+		4F23B9FD13B647A00097A67E /* knob.png in Resources */ = {isa = PBXBuildFile; fileRef = 4F23B9E413B647A00097A67E /* knob.png */; };
+		4F23BA0C13B647A00097A67E /* knob.png in Resources */ = {isa = PBXBuildFile; fileRef = 4F23B9E413B647A00097A67E /* knob.png */; };
+		4F296BDA1678E6C800C0F5C2 /* dfx-au-utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = 4FA88B901444E4C4006CB8DA /* dfx-au-utilities.c */; };
+		4F3AE17B12C0E5E2001FD7A4 /* resource.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBED30D0CF143001C8B8A /* resource.h */; };
+		4F3AE17C12C0E5E2001FD7A4 /* AccessiblePeakMeter.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBED20D0CF13D001C8B8A /* AccessiblePeakMeter.h */; };
+		4F3AE1A312C0E5E2001FD7A4 /* AccessiblePeakMeter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBED00D0CF139001C8B8A /* AccessiblePeakMeter.cpp */; };
+		4F3AE1D412C0E5E2001FD7A4 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52C4DB180D0E51270007A920 /* Carbon.framework */; };
+		4F3AE1D512C0E5E2001FD7A4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
+		4F3AE1D612C0E5E2001FD7A4 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52E41D920D14C2D600A0943B /* AudioToolbox.framework */; };
+		4F3AE1D712C0E5E2001FD7A4 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52E41D7E0D14C2D100A0943B /* AudioUnit.framework */; };
+		4F3AE1D812C0E5E2001FD7A4 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52E41CC40D14C2B000A0943B /* CoreServices.framework */; };
+		4F3AE1D912C0E5E2001FD7A4 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52E41CB90D14C2A900A0943B /* CoreAudio.framework */; };
+		4F3B0B44158B50A5001B0CEF /* libAAXLibrary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F8B6723158B4EB2002FC25B /* libAAXLibrary.a */; };
+		4F3EE94613B65A350097B791 /* IPlugOSDetect.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F3EE94513B65A350097B791 /* IPlugOSDetect.h */; };
+		4F3EE94913B65A350097B791 /* IPlugOSDetect.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F3EE94513B65A350097B791 /* IPlugOSDetect.h */; };
+		4F78D70B13B637340032E0F3 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F78D62313B637200032E0F3 /* CoreFoundation.framework */; };
+		4F78D7D013B637790032E0F3 /* CoreMIDI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F78D7CF13B637790032E0F3 /* CoreMIDI.framework */; };
+		4F78D86E13B637A20032E0F3 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2F7E65807B2D6F200F64583 /* CoreData.framework */; };
+		4F78D87013B637A20032E0F3 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52E41CB90D14C2A900A0943B /* CoreAudio.framework */; };
+		4F78D87113B637A20032E0F3 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
+		4F78D87513B637E50032E0F3 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52C4DB180D0E51270007A920 /* Carbon.framework */; };
+		4F78D88613B6382B0032E0F3 /* AccessiblePeakMeter.icns in Resources */ = {isa = PBXBuildFile; fileRef = 4FD290A8137C34D700CEBE7E /* AccessiblePeakMeter.icns */; };
+		4F78D89913B639100032E0F3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4F78D89513B639100032E0F3 /* InfoPlist.strings */; };
+		4F78D89A13B639100032E0F3 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4F78D89713B639100032E0F3 /* MainMenu.xib */; };
+		4F78D8C413B63A700032E0F3 /* RtAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8BF13B63A700032E0F3 /* RtAudio.cpp */; };
+		4F78D8C513B63A700032E0F3 /* RtMidi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8C213B63A700032E0F3 /* RtMidi.cpp */; };
+		4F78D8D913B63B5D0032E0F3 /* aeffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8D213B63B5D0032E0F3 /* aeffect.h */; };
+		4F78D8DA13B63B5D0032E0F3 /* aeffectx.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8D313B63B5D0032E0F3 /* aeffectx.h */; };
+		4F78D90A13B63BA50032E0F3 /* IPlugStandalone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8EB13B63BA40032E0F3 /* IPlugStandalone.cpp */; };
+		4F78D90B13B63BA50032E0F3 /* IPlugBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8ED13B63BA40032E0F3 /* IPlugBase.cpp */; };
+		4F78D90C13B63BA50032E0F3 /* IPlugStructs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8EF13B63BA50032E0F3 /* IPlugStructs.cpp */; };
+		4F78D90D13B63BA50032E0F3 /* Hosts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F313B63BA50032E0F3 /* Hosts.cpp */; };
+		4F78D90F13B63BA50032E0F3 /* IGraphicsMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F513B63BA50032E0F3 /* IGraphicsMac.mm */; };
+		4F78D91013B63BA50032E0F3 /* IGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F613B63BA50032E0F3 /* IGraphics.cpp */; };
+		4F78D91113B63BA50032E0F3 /* IGraphicsCarbon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F713B63BA50032E0F3 /* IGraphicsCarbon.cpp */; };
+		4F78D91213B63BA50032E0F3 /* IGraphicsCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F813B63BA50032E0F3 /* IGraphicsCocoa.mm */; };
+		4F78D91313B63BA50032E0F3 /* Log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8FB13B63BA50032E0F3 /* Log.cpp */; };
+		4F78D91413B63BA50032E0F3 /* IPopupMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8FD13B63BA50032E0F3 /* IPopupMenu.cpp */; };
+		4F78D91813B63BA50032E0F3 /* IParam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D90413B63BA50032E0F3 /* IParam.cpp */; };
+		4F78D91913B63BA50032E0F3 /* IControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D90913B63BA50032E0F3 /* IControl.cpp */; };
+		4F78D93E13B63BA50032E0F3 /* IPlug_include_in_plug_hdr.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8E613B63BA40032E0F3 /* IPlug_include_in_plug_hdr.h */; };
+		4F78D94013B63BA50032E0F3 /* IPlug_include_in_plug_src.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8E813B63BA40032E0F3 /* IPlug_include_in_plug_src.h */; };
+		4F78D94113B63BA50032E0F3 /* IControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8E913B63BA40032E0F3 /* IControl.h */; };
+		4F78D94213B63BA50032E0F3 /* IKeyboardControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8EA13B63BA40032E0F3 /* IKeyboardControl.h */; };
+		4F78D94413B63BA50032E0F3 /* IPlugBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8EC13B63BA40032E0F3 /* IPlugBase.h */; };
+		4F78D94513B63BA50032E0F3 /* IPlugBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8ED13B63BA40032E0F3 /* IPlugBase.cpp */; };
+		4F78D94613B63BA50032E0F3 /* IGraphicsMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8EE13B63BA50032E0F3 /* IGraphicsMac.h */; };
+		4F78D94713B63BA50032E0F3 /* IPlugStructs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8EF13B63BA50032E0F3 /* IPlugStructs.cpp */; };
+		4F78D94913B63BA50032E0F3 /* Containers.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8F113B63BA50032E0F3 /* Containers.h */; };
+		4F78D94A13B63BA50032E0F3 /* Hosts.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8F213B63BA50032E0F3 /* Hosts.h */; };
+		4F78D94B13B63BA50032E0F3 /* Hosts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F313B63BA50032E0F3 /* Hosts.cpp */; };
+		4F78D94D13B63BA50032E0F3 /* IGraphicsMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F513B63BA50032E0F3 /* IGraphicsMac.mm */; };
+		4F78D94E13B63BA50032E0F3 /* IGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F613B63BA50032E0F3 /* IGraphics.cpp */; };
+		4F78D94F13B63BA50032E0F3 /* IGraphicsCarbon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F713B63BA50032E0F3 /* IGraphicsCarbon.cpp */; };
+		4F78D95013B63BA50032E0F3 /* IGraphicsCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F813B63BA50032E0F3 /* IGraphicsCocoa.mm */; };
+		4F78D95113B63BA50032E0F3 /* IGraphicsCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8F913B63BA50032E0F3 /* IGraphicsCocoa.h */; };
+		4F78D95213B63BA50032E0F3 /* Log.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8FA13B63BA50032E0F3 /* Log.h */; };
+		4F78D95313B63BA50032E0F3 /* Log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8FB13B63BA50032E0F3 /* Log.cpp */; };
+		4F78D95413B63BA50032E0F3 /* IPopupMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8FC13B63BA50032E0F3 /* IPopupMenu.h */; };
+		4F78D95513B63BA50032E0F3 /* IPopupMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8FD13B63BA50032E0F3 /* IPopupMenu.cpp */; };
+		4F78D95613B63BA50032E0F3 /* IPlugStructs.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8FE13B63BA50032E0F3 /* IPlugStructs.h */; };
+		4F78D95A13B63BA50032E0F3 /* IPlug_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D90213B63BA50032E0F3 /* IPlug_Prefix.pch */; };
+		4F78D95B13B63BA50032E0F3 /* IParam.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D90313B63BA50032E0F3 /* IParam.h */; };
+		4F78D95C13B63BA50032E0F3 /* IParam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D90413B63BA50032E0F3 /* IParam.cpp */; };
+		4F78D95D13B63BA50032E0F3 /* IMidiQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D90513B63BA50032E0F3 /* IMidiQueue.h */; };
+		4F78D95F13B63BA50032E0F3 /* IGraphicsCarbon.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D90713B63BA50032E0F3 /* IGraphicsCarbon.h */; };
+		4F78D96013B63BA50032E0F3 /* IGraphics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D90813B63BA50032E0F3 /* IGraphics.h */; };
+		4F78D96113B63BA50032E0F3 /* IControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D90913B63BA50032E0F3 /* IControl.cpp */; };
+		4F78D9BB13B63BA50032E0F3 /* IPlugBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8ED13B63BA40032E0F3 /* IPlugBase.cpp */; };
+		4F78D9BC13B63BA50032E0F3 /* IPlugStructs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8EF13B63BA50032E0F3 /* IPlugStructs.cpp */; };
+		4F78D9BD13B63BA50032E0F3 /* Hosts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F313B63BA50032E0F3 /* Hosts.cpp */; };
+		4F78D9BF13B63BA50032E0F3 /* IGraphicsMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F513B63BA50032E0F3 /* IGraphicsMac.mm */; };
+		4F78D9C013B63BA50032E0F3 /* IGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F613B63BA50032E0F3 /* IGraphics.cpp */; };
+		4F78D9C113B63BA50032E0F3 /* IGraphicsCarbon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F713B63BA50032E0F3 /* IGraphicsCarbon.cpp */; };
+		4F78D9C213B63BA50032E0F3 /* IGraphicsCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F813B63BA50032E0F3 /* IGraphicsCocoa.mm */; };
+		4F78D9C313B63BA50032E0F3 /* Log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8FB13B63BA50032E0F3 /* Log.cpp */; };
+		4F78D9C413B63BA50032E0F3 /* IPopupMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8FD13B63BA50032E0F3 /* IPopupMenu.cpp */; };
+		4F78D9C813B63BA50032E0F3 /* IParam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D90413B63BA50032E0F3 /* IParam.cpp */; };
+		4F78D9C913B63BA50032E0F3 /* IControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D90913B63BA50032E0F3 /* IControl.cpp */; };
+		4F78D9F313B63C6A0032E0F3 /* IPlugVST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D9EC13B63C6A0032E0F3 /* IPlugVST.cpp */; };
+		4F78DA0713B63CD90032E0F3 /* IPlugAU.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D9FB13B63CD90032E0F3 /* IPlugAU.h */; };
+		4F78DA0813B63CD90032E0F3 /* IPlugAU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D9FC13B63CD90032E0F3 /* IPlugAU.cpp */; };
+		4F78DA0913B63CD90032E0F3 /* IPlugAU.r in Rez */ = {isa = PBXBuildFile; fileRef = 4F78D9FD13B63CD90032E0F3 /* IPlugAU.r */; };
+		4F78DA0A13B63CD90032E0F3 /* IPlugAU_ViewFactory.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D9FE13B63CD90032E0F3 /* IPlugAU_ViewFactory.mm */; };
+		4F78DA5A13B63F150032E0F3 /* AccessiblePeakMeter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBED00D0CF139001C8B8A /* AccessiblePeakMeter.cpp */; };
+		4F78DA7713B640050032E0F3 /* resource.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBED30D0CF143001C8B8A /* resource.h */; };
+		4F78DA7813B640050032E0F3 /* AccessiblePeakMeter.h in Headers */ = {isa = PBXBuildFile; fileRef = 52FBBED20D0CF13D001C8B8A /* AccessiblePeakMeter.h */; };
+		4F78DA8A13B640050032E0F3 /* mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FF016F4134E14E2001447BA /* mutex.h */; };
+		4F78DA8B13B640050032E0F3 /* ptrlist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FF016F5134E14E2001447BA /* ptrlist.h */; };
+		4F78DA8C13B640050032E0F3 /* wdlstring.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FF016F6134E14E2001447BA /* wdlstring.h */; };
+		4F78DA8D13B640050032E0F3 /* heapbuf.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FF01719134E153A001447BA /* heapbuf.h */; };
+		4F78DA8E13B640050032E0F3 /* wdlendian.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F1F1BE9135B1F60003A5BB2 /* wdlendian.h */; };
+		4F78DA8F13B640050032E0F3 /* swell.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FD16D1713B634E5001D0217 /* swell.h */; };
+		4F78DA9013B640050032E0F3 /* swell-functions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FD16D2213B6351C001D0217 /* swell-functions.h */; };
+		4F78DA9113B640050032E0F3 /* swell-internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FD16D2B13B6353C001D0217 /* swell-internal.h */; };
+		4F78DA9213B640050032E0F3 /* swell-types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FD16D3013B6355A001D0217 /* swell-types.h */; };
+		4F78DA9313B640050032E0F3 /* aeffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8D213B63B5D0032E0F3 /* aeffect.h */; };
+		4F78DA9413B640050032E0F3 /* aeffectx.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8D313B63B5D0032E0F3 /* aeffectx.h */; };
+		4F78DA9513B640050032E0F3 /* IPlug_include_in_plug_hdr.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8E613B63BA40032E0F3 /* IPlug_include_in_plug_hdr.h */; };
+		4F78DA9613B640050032E0F3 /* IPlug_include_in_plug_src.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8E813B63BA40032E0F3 /* IPlug_include_in_plug_src.h */; };
+		4F78DA9713B640050032E0F3 /* IControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8E913B63BA40032E0F3 /* IControl.h */; };
+		4F78DA9813B640050032E0F3 /* IKeyboardControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8EA13B63BA40032E0F3 /* IKeyboardControl.h */; };
+		4F78DA9913B640050032E0F3 /* IPlugBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8EC13B63BA40032E0F3 /* IPlugBase.h */; };
+		4F78DA9A13B640050032E0F3 /* IGraphicsMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8EE13B63BA50032E0F3 /* IGraphicsMac.h */; };
+		4F78DA9C13B640050032E0F3 /* Containers.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8F113B63BA50032E0F3 /* Containers.h */; };
+		4F78DA9D13B640050032E0F3 /* Hosts.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8F213B63BA50032E0F3 /* Hosts.h */; };
+		4F78DA9E13B640050032E0F3 /* IGraphicsCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8F913B63BA50032E0F3 /* IGraphicsCocoa.h */; };
+		4F78DA9F13B640050032E0F3 /* Log.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8FA13B63BA50032E0F3 /* Log.h */; };
+		4F78DAA013B640050032E0F3 /* IPopupMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8FC13B63BA50032E0F3 /* IPopupMenu.h */; };
+		4F78DAA113B640050032E0F3 /* IPlugStructs.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8FE13B63BA50032E0F3 /* IPlugStructs.h */; };
+		4F78DAA213B640050032E0F3 /* IPlug_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D90213B63BA50032E0F3 /* IPlug_Prefix.pch */; };
+		4F78DAA313B640050032E0F3 /* IParam.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D90313B63BA50032E0F3 /* IParam.h */; };
+		4F78DAA413B640050032E0F3 /* IMidiQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D90513B63BA50032E0F3 /* IMidiQueue.h */; };
+		4F78DAA513B640050032E0F3 /* IGraphicsCarbon.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D90713B63BA50032E0F3 /* IGraphicsCarbon.h */; };
+		4F78DAA613B640050032E0F3 /* IGraphics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D90813B63BA50032E0F3 /* IGraphics.h */; };
+		4F78DAB113B640470032E0F3 /* swell-menugen.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FD16D0213B63489001D0217 /* swell-menugen.h */; };
+		4F78DAB213B640470032E0F3 /* swell-dlggen.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FD16D0313B63494001D0217 /* swell-dlggen.h */; };
+		4F78DAB313B640470032E0F3 /* swellappmain.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FD16D4513B635C8001D0217 /* swellappmain.h */; };
+		4F78DAB813B640530032E0F3 /* RtAudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8C013B63A700032E0F3 /* RtAudio.h */; };
+		4F78DAB913B640530032E0F3 /* RtError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8C113B63A700032E0F3 /* RtError.h */; };
+		4F78DABA13B640530032E0F3 /* RtMidi.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D8C313B63A700032E0F3 /* RtMidi.h */; };
+		4F78DABB13B640620032E0F3 /* IPlugStandalone.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F78D9EA13B63BE90032E0F3 /* IPlugStandalone.h */; };
+		4F79A34E146304CD00744AED /* IPlugProcessAS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F79A34C146304CD00744AED /* IPlugProcessAS.cpp */; };
+		4F7E1EB516792F6000907FCF /* bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 4F7E1EB116792F6000907FCF /* bg.png */; };
+		4F7E1EB916792F6000907FCF /* bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 4F7E1EB116792F6000907FCF /* bg.png */; };
+		4F7E1EBD16792F6000907FCF /* bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 4F7E1EB116792F6000907FCF /* bg.png */; };
+		4F7E1EC116792F6000907FCF /* bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 4F7E1EB116792F6000907FCF /* bg.png */; };
+		4F7E1EC516792F6000907FCF /* bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 4F7E1EB116792F6000907FCF /* bg.png */; };
+		4F7E1EC916792F6000907FCF /* bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 4F7E1EB116792F6000907FCF /* bg.png */; };
+		4F7F5C4613E95EC8002918FD /* knob.png in Resources */ = {isa = PBXBuildFile; fileRef = 4F23B9E413B647A00097A67E /* knob.png */; };
+		4F7F5C4913E95EC8002918FD /* AccessiblePeakMeter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBED00D0CF139001C8B8A /* AccessiblePeakMeter.cpp */; };
+		4F7F5C5013E95EC8002918FD /* swell-gdi.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D0B13B634BF001D0217 /* swell-gdi.mm */; };
+		4F7F5C5113E95EC8002918FD /* IPlugBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8ED13B63BA40032E0F3 /* IPlugBase.cpp */; };
+		4F7F5C5213E95EC8002918FD /* IPlugStructs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8EF13B63BA50032E0F3 /* IPlugStructs.cpp */; };
+		4F7F5C5313E95EC8002918FD /* Hosts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F313B63BA50032E0F3 /* Hosts.cpp */; };
+		4F7F5C5413E95EC8002918FD /* IGraphicsMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F513B63BA50032E0F3 /* IGraphicsMac.mm */; };
+		4F7F5C5513E95EC8002918FD /* IGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F613B63BA50032E0F3 /* IGraphics.cpp */; };
+		4F7F5C5613E95EC8002918FD /* IGraphicsCarbon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F713B63BA50032E0F3 /* IGraphicsCarbon.cpp */; };
+		4F7F5C5713E95EC8002918FD /* IGraphicsCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F813B63BA50032E0F3 /* IGraphicsCocoa.mm */; };
+		4F7F5C5813E95EC8002918FD /* Log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8FB13B63BA50032E0F3 /* Log.cpp */; };
+		4F7F5C5913E95EC8002918FD /* IPopupMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8FD13B63BA50032E0F3 /* IPopupMenu.cpp */; };
+		4F7F5C5A13E95EC8002918FD /* IParam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D90413B63BA50032E0F3 /* IParam.cpp */; };
+		4F7F5C5B13E95EC8002918FD /* IControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D90913B63BA50032E0F3 /* IControl.cpp */; };
+		4F7F5C6213E95EC8002918FD /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
+		4F7F5C6313E95EC8002918FD /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52C4DB180D0E51270007A920 /* Carbon.framework */; };
+		4F7F5C7113E95FB2002918FD /* IPlugRTAS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F7F5C6F13E95FB2002918FD /* IPlugRTAS.cpp */; };
+		4F7F5CAD13E9607A002918FD /* digicode1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F7F5C9C13E9607A002918FD /* digicode1.cpp */; };
+		4F7F5CAE13E9607A002918FD /* digicode2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F7F5C9D13E9607A002918FD /* digicode2.cpp */; };
+		4F7F5CAF13E9607A002918FD /* digicode3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F7F5C9E13E9607A002918FD /* digicode3.cpp */; };
+		4F7F5CB013E9607A002918FD /* IPlugCustomUI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F7F5CA013E9607A002918FD /* IPlugCustomUI.cpp */; };
+		4F7F5CB113E9607A002918FD /* IPlugGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F7F5CA313E9607A002918FD /* IPlugGroup.cpp */; };
+		4F7F5CB213E9607A002918FD /* IPlugProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F7F5CA513E9607A002918FD /* IPlugProcess.cpp */; };
+		4F7F5CB313E9607A002918FD /* IPlugProcessRTAS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F7F5CA713E9607A002918FD /* IPlugProcessRTAS.cpp */; };
+		4F7F5CF713E96564002918FD /* System.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F7F5CF613E96564002918FD /* System.framework */; };
+		4F7F5D2C13E9686E002918FD /* IPlugRTAS.r in Rez */ = {isa = PBXBuildFile; fileRef = 4F7F5D2413E9681E002918FD /* IPlugRTAS.r */; };
+		4F8B6766158B4F74002FC25B /* libPluginLibrary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F8B674F158B4F53002FC25B /* libPluginLibrary.a */; };
+		4F8D4BCD13E97671004F7633 /* lice.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F8D4BCC13E97664004F7633 /* lice.a */; };
+		4F8D4C2813E9778D004F7633 /* lice.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F8D4BCC13E97664004F7633 /* lice.a */; };
+		4F8D4C2913E97794004F7633 /* lice32.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F8D4C1713E976A7004F7633 /* lice32.a */; };
+		4F8D4C2F13E97806004F7633 /* lice.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F8D4BCC13E97664004F7633 /* lice.a */; };
+		4F9828B1140A9EB700F3FCC1 /* knob.png in Resources */ = {isa = PBXBuildFile; fileRef = 4F23B9E413B647A00097A67E /* knob.png */; };
+		4F9828B6140A9EB700F3FCC1 /* AccessiblePeakMeter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBED00D0CF139001C8B8A /* AccessiblePeakMeter.cpp */; };
+		4F9828B7140A9EB700F3FCC1 /* swell-gdi.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D0B13B634BF001D0217 /* swell-gdi.mm */; };
+		4F9828B8140A9EB700F3FCC1 /* IPlugBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8ED13B63BA40032E0F3 /* IPlugBase.cpp */; };
+		4F9828B9140A9EB700F3FCC1 /* IPlugStructs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8EF13B63BA50032E0F3 /* IPlugStructs.cpp */; };
+		4F9828BA140A9EB700F3FCC1 /* Hosts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F313B63BA50032E0F3 /* Hosts.cpp */; };
+		4F9828BB140A9EB700F3FCC1 /* IGraphicsMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F513B63BA50032E0F3 /* IGraphicsMac.mm */; };
+		4F9828BC140A9EB700F3FCC1 /* IGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F613B63BA50032E0F3 /* IGraphics.cpp */; };
+		4F9828BD140A9EB700F3FCC1 /* IGraphicsCarbon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F713B63BA50032E0F3 /* IGraphicsCarbon.cpp */; };
+		4F9828BE140A9EB700F3FCC1 /* IGraphicsCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F813B63BA50032E0F3 /* IGraphicsCocoa.mm */; };
+		4F9828BF140A9EB700F3FCC1 /* Log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8FB13B63BA50032E0F3 /* Log.cpp */; };
+		4F9828C0140A9EB700F3FCC1 /* IPopupMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8FD13B63BA50032E0F3 /* IPopupMenu.cpp */; };
+		4F9828C1140A9EB700F3FCC1 /* IParam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D90413B63BA50032E0F3 /* IParam.cpp */; };
+		4F9828C2140A9EB700F3FCC1 /* IControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D90913B63BA50032E0F3 /* IControl.cpp */; };
+		4F9828C3140A9EB700F3FCC1 /* IBitmapMonoText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FDA440513F3E4F2000B4551 /* IBitmapMonoText.cpp */; };
+		4F9828C4140A9EB700F3FCC1 /* IPlugVST3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F3E69041409746500C4D749 /* IPlugVST3.cpp */; };
+		4F9828C5140A9EB700F3FCC1 /* memorystream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4ACFF5140996A10068A6D4 /* memorystream.cpp */; };
+		4F9828C6140A9EB700F3FCC1 /* pluginview.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4ACFF7140996A10068A6D4 /* pluginview.cpp */; };
+		4F9828C7140A9EB700F3FCC1 /* macmain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4ACFFB140996A10068A6D4 /* macmain.cpp */; };
+		4F9828C8140A9EB700F3FCC1 /* pluginfactoryvst3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4ACFFC140996A10068A6D4 /* pluginfactoryvst3.cpp */; };
+		4F9828C9140A9EB700F3FCC1 /* vstaudioeffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4ACFFF140996A10068A6D4 /* vstaudioeffect.cpp */; };
+		4F9828CA140A9EB700F3FCC1 /* vstbus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4AD001140996A10068A6D4 /* vstbus.cpp */; };
+		4F9828CB140A9EB700F3FCC1 /* vstcomponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4AD003140996A10068A6D4 /* vstcomponent.cpp */; };
+		4F9828CC140A9EB700F3FCC1 /* vstcomponentbase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4AD005140996A10068A6D4 /* vstcomponentbase.cpp */; };
+		4F9828CE140A9EB700F3FCC1 /* vstinitiids.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4AD009140996A10068A6D4 /* vstinitiids.cpp */; };
+		4F9828CF140A9EB700F3FCC1 /* vstnoteexpressiontypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4AD00A140996A10068A6D4 /* vstnoteexpressiontypes.cpp */; };
+		4F9828D0140A9EB700F3FCC1 /* vstparameters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4AD00C140996A10068A6D4 /* vstparameters.cpp */; };
+		4F9828D1140A9EB700F3FCC1 /* vstpresetfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4AD00E140996A10068A6D4 /* vstpresetfile.cpp */; };
+		4F9828D2140A9EB700F3FCC1 /* vstrepresentation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4AD010140996A10068A6D4 /* vstrepresentation.cpp */; };
+		4F9828D3140A9EB700F3FCC1 /* vstsinglecomponenteffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4AD012140996A10068A6D4 /* vstsinglecomponenteffect.cpp */; };
+		4F9828D4140A9EB700F3FCC1 /* conststringtable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4AD016140996A10068A6D4 /* conststringtable.cpp */; };
+		4F9828D5140A9EB700F3FCC1 /* funknown.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4AD01D140996A10068A6D4 /* funknown.cpp */; };
+		4F9828D6140A9EB700F3FCC1 /* ustring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4AD028140996A10068A6D4 /* ustring.cpp */; };
+		4F9828D8140A9EB700F3FCC1 /* libbase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F4AD1F61409A56A0068A6D4 /* libbase.a */; };
+		4F9828DA140A9EB700F3FCC1 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
+		4F9828DB140A9EB700F3FCC1 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52C4DB180D0E51270007A920 /* Carbon.framework */; };
+		4F9828F6140A9EEE00F3FCC1 /* lice.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F8D4BCC13E97664004F7633 /* lice.a */; };
+		4FA88B931444E4C4006CB8DA /* dfx-au-utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FA88B911444E4C4006CB8DA /* dfx-au-utilities.h */; };
+		4FB3624F13B648FE00DB6B76 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FB3624E13B648FE00DB6B76 /* main.mm */; };
+		4FB600161567CB0A0020189A /* knob.png in Resources */ = {isa = PBXBuildFile; fileRef = 4F23B9E413B647A00097A67E /* knob.png */; };
+		4FB600181567CB0A0020189A /* AccessiblePeakMeter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52FBBED00D0CF139001C8B8A /* AccessiblePeakMeter.cpp */; };
+		4FB600191567CB0A0020189A /* swell-gdi.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D0B13B634BF001D0217 /* swell-gdi.mm */; };
+		4FB6001A1567CB0A0020189A /* IPlugBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8ED13B63BA40032E0F3 /* IPlugBase.cpp */; };
+		4FB6001B1567CB0A0020189A /* IPlugStructs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8EF13B63BA50032E0F3 /* IPlugStructs.cpp */; };
+		4FB6001C1567CB0A0020189A /* Hosts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F313B63BA50032E0F3 /* Hosts.cpp */; };
+		4FB6001D1567CB0A0020189A /* IGraphicsMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F513B63BA50032E0F3 /* IGraphicsMac.mm */; };
+		4FB6001E1567CB0A0020189A /* IGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F613B63BA50032E0F3 /* IGraphics.cpp */; };
+		4FB6001F1567CB0A0020189A /* IGraphicsCarbon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F713B63BA50032E0F3 /* IGraphicsCarbon.cpp */; };
+		4FB600201567CB0A0020189A /* IGraphicsCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8F813B63BA50032E0F3 /* IGraphicsCocoa.mm */; };
+		4FB600211567CB0A0020189A /* Log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8FB13B63BA50032E0F3 /* Log.cpp */; };
+		4FB600221567CB0A0020189A /* IPopupMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D8FD13B63BA50032E0F3 /* IPopupMenu.cpp */; };
+		4FB600231567CB0A0020189A /* IParam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D90413B63BA50032E0F3 /* IParam.cpp */; };
+		4FB600241567CB0A0020189A /* IControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F78D90913B63BA50032E0F3 /* IControl.cpp */; };
+		4FB600251567CB0A0020189A /* IBitmapMonoText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FDA440513F3E4F2000B4551 /* IBitmapMonoText.cpp */; };
+		4FB600261567CB0A0020189A /* AAX_Exports.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4CC38A1549B91100A9EA21 /* AAX_Exports.cpp */; };
+		4FB600271567CB0A0020189A /* IPlugAAX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4CC4251549BED600A9EA21 /* IPlugAAX.cpp */; };
+		4FB600281567CB0A0020189A /* IPlugAAX_Describe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F4CC4401549C15500A9EA21 /* IPlugAAX_Describe.cpp */; };
+		4FB600291567CB0A0020189A /* AAX_CIPlugParameters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F017360154D4BFC0034BE1A /* AAX_CIPlugParameters.cpp */; };
+		4FB6002C1567CB0A0020189A /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
+		4FB6002D1567CB0A0020189A /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52C4DB180D0E51270007A920 /* Carbon.framework */; };
+		4FB600551567CBF90020189A /* lice.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F8D4BCC13E97664004F7633 /* lice.a */; };
+		4FD16CA213B6327D001D0217 /* app_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16CA013B6327C001D0217 /* app_main.cpp */; };
+		4FD16CA313B6327D001D0217 /* app_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16CA113B6327C001D0217 /* app_dialog.cpp */; };
+		4FD16CFC13B63468001D0217 /* swell-appstub.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16CFB13B63468001D0217 /* swell-appstub.mm */; };
+		4FD16D0513B634AA001D0217 /* swell-dlg.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D0413B634AA001D0217 /* swell-dlg.mm */; };
+		4FD16D0C13B634BF001D0217 /* swell-gdi.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D0B13B634BF001D0217 /* swell-gdi.mm */; };
+		4FD16D0E13B634BF001D0217 /* swell-gdi.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D0B13B634BF001D0217 /* swell-gdi.mm */; };
+		4FD16D1213B634BF001D0217 /* swell-gdi.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D0B13B634BF001D0217 /* swell-gdi.mm */; };
+		4FD16D1613B634D2001D0217 /* swell-ini.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D1513B634D2001D0217 /* swell-ini.cpp */; };
+		4FD16D1913B634E5001D0217 /* swell.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FD16D1713B634E5001D0217 /* swell.h */; };
+		4FD16D2413B6351C001D0217 /* swell-functions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FD16D2213B6351C001D0217 /* swell-functions.h */; };
+		4FD16D2D13B6353C001D0217 /* swell-internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FD16D2B13B6353C001D0217 /* swell-internal.h */; };
+		4FD16D3213B6355A001D0217 /* swell-types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FD16D3013B6355A001D0217 /* swell-types.h */; };
+		4FD16D3A13B63582001D0217 /* swell-kb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D3913B63582001D0217 /* swell-kb.mm */; };
+		4FD16D3C13B6358C001D0217 /* swell-miscdlg.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D3B13B6358C001D0217 /* swell-miscdlg.mm */; };
+		4FD16D3E13B63595001D0217 /* swell-menu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D3D13B63595001D0217 /* swell-menu.mm */; };
+		4FD16D4013B635A0001D0217 /* swell-misc.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D3F13B635A0001D0217 /* swell-misc.mm */; };
+		4FD16D4213B635AB001D0217 /* swell-wnd.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D4113B635AB001D0217 /* swell-wnd.mm */; };
+		4FD16D4413B635B2001D0217 /* swell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D4313B635B2001D0217 /* swell.cpp */; };
+		4FD16D4713B635C8001D0217 /* swellappmain.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4FD16D4613B635C8001D0217 /* swellappmain.mm */; };
+		4FDA440713F3E4F2000B4551 /* IBitmapMonoText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FDA440513F3E4F2000B4551 /* IBitmapMonoText.cpp */; };
+		4FDA440813F3E4F2000B4551 /* IBitmapMonoText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FDA440513F3E4F2000B4551 /* IBitmapMonoText.cpp */; };
+		4FDA440913F3E4F2000B4551 /* IBitmapMonoText.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FDA440613F3E4F2000B4551 /* IBitmapMonoText.h */; };
+		4FDA440C13F3E4F2000B4551 /* IBitmapMonoText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FDA440513F3E4F2000B4551 /* IBitmapMonoText.cpp */; };
+		4FDA440E13F3E4F2000B4551 /* IBitmapMonoText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FDA440513F3E4F2000B4551 /* IBitmapMonoText.cpp */; };
+		4FDA440F13F3E4F2000B4551 /* IBitmapMonoText.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FDA440613F3E4F2000B4551 /* IBitmapMonoText.h */; };
+		4FF016F7134E14E2001447BA /* mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FF016F4134E14E2001447BA /* mutex.h */; };
+		4FF016F8134E14E2001447BA /* ptrlist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FF016F5134E14E2001447BA /* ptrlist.h */; };
+		4FF016F9134E14E2001447BA /* wdlstring.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FF016F6134E14E2001447BA /* wdlstring.h */; };
+		4FF0171A134E153A001447BA /* heapbuf.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FF01719134E153A001447BA /* heapbuf.h */; };
+		5EDC2A811A93B020004EFD46 /* ADSR.h in Headers */ = {isa = PBXBuildFile; fileRef = 5EDC2A771A93B020004EFD46 /* ADSR.h */; };
+		5EDC2A821A93B020004EFD46 /* Envelope.h in Headers */ = {isa = PBXBuildFile; fileRef = 5EDC2A781A93B020004EFD46 /* Envelope.h */; };
+		5EDC2A831A93B020004EFD46 /* Generator.h in Headers */ = {isa = PBXBuildFile; fileRef = 5EDC2A791A93B020004EFD46 /* Generator.h */; };
+		5EDC2A841A93B020004EFD46 /* SineWave.h in Headers */ = {isa = PBXBuildFile; fileRef = 5EDC2A7A1A93B020004EFD46 /* SineWave.h */; };
+		5EDC2A851A93B020004EFD46 /* Stk.h in Headers */ = {isa = PBXBuildFile; fileRef = 5EDC2A7B1A93B020004EFD46 /* Stk.h */; };
+		5EDC2A861A93B020004EFD46 /* ADSR.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EDC2A7D1A93B020004EFD46 /* ADSR.cpp */; };
+		5EDC2A871A93B020004EFD46 /* ADSR.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EDC2A7D1A93B020004EFD46 /* ADSR.cpp */; };
+		5EDC2A881A93B020004EFD46 /* Envelope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EDC2A7E1A93B020004EFD46 /* Envelope.cpp */; };
+		5EDC2A891A93B020004EFD46 /* Envelope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EDC2A7E1A93B020004EFD46 /* Envelope.cpp */; };
+		5EDC2A8A1A93B020004EFD46 /* SineWave.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EDC2A7F1A93B020004EFD46 /* SineWave.cpp */; };
+		5EDC2A8B1A93B020004EFD46 /* SineWave.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EDC2A7F1A93B020004EFD46 /* SineWave.cpp */; };
+		5EDC2A8C1A93B020004EFD46 /* Stk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EDC2A801A93B020004EFD46 /* Stk.cpp */; };
+		5EDC2A8D1A93B020004EFD46 /* Stk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EDC2A801A93B020004EFD46 /* Stk.cpp */; };
+		5EDC2A961A93BA2E004EFD46 /* switch.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EDC2A951A93B343004EFD46 /* switch.png */; };
+		5EDC2A971A93BA2E004EFD46 /* switch.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EDC2A951A93B343004EFD46 /* switch.png */; };
+		5EDC2A981A93BA2F004EFD46 /* switch.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EDC2A951A93B343004EFD46 /* switch.png */; };
+		5EDC2A991A93BA2F004EFD46 /* switch.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EDC2A951A93B343004EFD46 /* switch.png */; };
+		5EDC2A9A1A93BA30004EFD46 /* switch.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EDC2A951A93B343004EFD46 /* switch.png */; };
+		5EDC2A9B1A93BA30004EFD46 /* switch.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EDC2A951A93B343004EFD46 /* switch.png */; };
+		5EDC2A9C1A93BA33004EFD46 /* fader.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EDC2A921A93B337004EFD46 /* fader.png */; };
+		5EDC2A9D1A93BA33004EFD46 /* fader.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EDC2A921A93B337004EFD46 /* fader.png */; };
+		5EDC2A9E1A93BA34004EFD46 /* fader.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EDC2A921A93B337004EFD46 /* fader.png */; };
+		5EDC2A9F1A93BA34004EFD46 /* fader.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EDC2A921A93B337004EFD46 /* fader.png */; };
+		5EDC2AA01A93BA34004EFD46 /* fader.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EDC2A921A93B337004EFD46 /* fader.png */; };
+		5EDC2AA11A93BA35004EFD46 /* fader.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EDC2A921A93B337004EFD46 /* fader.png */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		4F3B0B42158B509A001B0CEF /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4FF7B0F3156A831000E6CB12 /* AAXLibrary.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = D2AAC045055464E500DB518D;
+			remoteInfo = AAXLibrary;
+		};
+		4F4AD1F51409A56A0068A6D4 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4F4AD1F11409A56A0068A6D4 /* base.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = D2AAC046055464E500DB518D;
+			remoteInfo = base;
+		};
+		4F678B6C13E984B200A6A9BB /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4F8D4BC413E97664004F7633 /* lice.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = D2AAC045055464E500DB518D;
+			remoteInfo = "lice_32&64_intel";
+		};
+		4F789ECF16763E47009EF688 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 089C1669FE841209C02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 4FB600121567CB0A0020189A;
+			remoteInfo = "AAX_32&64_intel";
+		};
+		4F78DAF513B6436B0032E0F3 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 089C1669FE841209C02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 4FD16A0813B63081001D0217;
+			remoteInfo = "OSXAPP_32&64_intel";
+		};
+		4F78DAF713B6436B0032E0F3 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 089C1669FE841209C02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 4F20EEC8132C69FE0030E34C;
+			remoteInfo = "VST_32&64_intel";
+		};
+		4F78DAF913B6436B0032E0F3 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 089C1669FE841209C02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 4F3AE17812C0E5E2001FD7A4;
+			remoteInfo = "AU_32&64_intel";
+		};
+		4F8B6722158B4EB2002FC25B /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4FF7B0F3156A831000E6CB12 /* AAXLibrary.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = D2AAC046055464E500DB518D;
+			remoteInfo = AAXLibrary;
+		};
+		4F8B6724158B4EB2002FC25B /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4FF7B0F3156A831000E6CB12 /* AAXLibrary.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 4B00D06910E022FD00816F7B;
+			remoteInfo = AAXLibrary_UnitTest;
+		};
+		4F8B674E158B4F53002FC25B /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4F8B6747158B4F53002FC25B /* PluginLibrary.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = B65B09B30860FB0800FE2E6A;
+			remoteInfo = "Plugin Library";
+		};
+		4F8B6764158B4F67002FC25B /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4F8B6747158B4F53002FC25B /* PluginLibrary.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = B65B09B20860FB0800FE2E6A;
+			remoteInfo = "Plugin Library";
+		};
+		4F8D4BCB13E97664004F7633 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4F8D4BC413E97664004F7633 /* lice.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = D2AAC046055464E500DB518D;
+			remoteInfo = lice;
+		};
+		4F8D4C1613E976A7004F7633 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4F8D4BC413E97664004F7633 /* lice.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 4F8D4C1413E976A7004F7633;
+			remoteInfo = "lice copy";
+		};
+		4F8D4C2C13E977CD004F7633 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4F8D4BC413E97664004F7633 /* lice.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = D2AAC045055464E500DB518D;
+			remoteInfo = "lice_32&64_intel";
+		};
+		4F8D4C3713E9783A004F7633 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4F8D4BC413E97664004F7633 /* lice.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = 4F8D4BD513E976A7004F7633;
+			remoteInfo = lice_32_intel;
+		};
+		4F8D4C3913E97859004F7633 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4F8D4BC413E97664004F7633 /* lice.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = D2AAC045055464E500DB518D;
+			remoteInfo = "lice_32&64_intel";
+		};
+		4F8D4C6213E97B3D004F7633 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 089C1669FE841209C02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 4F7F5C4213E95EC8002918FD;
+			remoteInfo = RTAS_32_intel;
+		};
+		4F9828AE140A9EB700F3FCC1 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4F4AD1F11409A56A0068A6D4 /* base.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = D2AAC045055464E500DB518D;
+			remoteInfo = base;
+		};
+		4F9828F2140A9ED500F3FCC1 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4F8D4BC413E97664004F7633 /* lice.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = D2AAC045055464E500DB518D;
+			remoteInfo = "lice_32&64_intel";
+		};
+		4F9828F7140A9F0200F3FCC1 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 089C1669FE841209C02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 4F9828AA140A9EB700F3FCC1;
+			remoteInfo = "VST3_32&64_intel";
+		};
+		4FA708BE158B47F000BFC572 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4F4AD1F11409A56A0068A6D4 /* base.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 4FA708BC158B47D200BFC572;
+			remoteInfo = base_32;
+		};
+		4FB6004F1567CB990020189A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 4F8D4BC413E97664004F7633 /* lice.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = D2AAC045055464E500DB518D;
+			remoteInfo = "lice_32&64_intel";
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+		089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+		089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+		1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+		4F017360154D4BFC0034BE1A /* AAX_CIPlugParameters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AAX_CIPlugParameters.cpp; path = ../../WDL/IPlug/AAX/AAX_CIPlugParameters.cpp; sourceTree = SOURCE_ROOT; };
+		4F017361154D4BFC0034BE1A /* AAX_CIPlugParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AAX_CIPlugParameters.h; path = ../../WDL/IPlug/AAX/AAX_CIPlugParameters.h; sourceTree = SOURCE_ROOT; };
+		4F1F1BE9135B1F60003A5BB2 /* wdlendian.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wdlendian.h; path = ../../WDL/wdlendian.h; sourceTree = SOURCE_ROOT; };
+		4F20EF33132C69FE0030E34C /* AccessiblePeakMeter.vst */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AccessiblePeakMeter.vst; sourceTree = BUILT_PRODUCTS_DIR; };
+		4F23B9E413B647A00097A67E /* knob.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = knob.png; path = resources/img/knob.png; sourceTree = "<group>"; };
+		4F23BA1313B647E50097A67E /* AccessiblePeakMeter-AU-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "AccessiblePeakMeter-AU-Info.plist"; path = "resources/AccessiblePeakMeter-AU-Info.plist"; sourceTree = "<group>"; };
+		4F23BA1413B647E50097A67E /* AccessiblePeakMeter-OSXAPP-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "AccessiblePeakMeter-OSXAPP-Info.plist"; path = "resources/AccessiblePeakMeter-OSXAPP-Info.plist"; sourceTree = "<group>"; };
+		4F23BA1513B647E50097A67E /* AccessiblePeakMeter-VST2-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "AccessiblePeakMeter-VST2-Info.plist"; path = "resources/AccessiblePeakMeter-VST2-Info.plist"; sourceTree = "<group>"; };
+		4F3E69041409746500C4D749 /* IPlugVST3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugVST3.cpp; path = ../../WDL/IPlug/IPlugVST3.cpp; sourceTree = SOURCE_ROOT; };
+		4F3E69051409746500C4D749 /* IPlugVST3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugVST3.h; path = ../../WDL/IPlug/IPlugVST3.h; sourceTree = SOURCE_ROOT; };
+		4F3E693A1409747300C4D749 /* AccessiblePeakMeter-VST3-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "AccessiblePeakMeter-VST3-Info.plist"; path = "resources/AccessiblePeakMeter-VST3-Info.plist"; sourceTree = "<group>"; };
+		4F3EE94513B65A350097B791 /* IPlugOSDetect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugOSDetect.h; path = ../../WDL/IPlug/IPlugOSDetect.h; sourceTree = SOURCE_ROOT; };
+		4F4ACFF5140996A10068A6D4 /* memorystream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memorystream.cpp; sourceTree = "<group>"; };
+		4F4ACFF6140996A10068A6D4 /* memorystream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memorystream.h; sourceTree = "<group>"; };
+		4F4ACFF7140996A10068A6D4 /* pluginview.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pluginview.cpp; sourceTree = "<group>"; };
+		4F4ACFF8140996A10068A6D4 /* pluginview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pluginview.h; sourceTree = "<group>"; };
+		4F4ACFFB140996A10068A6D4 /* macmain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = macmain.cpp; sourceTree = "<group>"; };
+		4F4ACFFC140996A10068A6D4 /* pluginfactoryvst3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pluginfactoryvst3.cpp; sourceTree = "<group>"; };
+		4F4ACFFD140996A10068A6D4 /* pluginfactoryvst3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pluginfactoryvst3.h; sourceTree = "<group>"; };
+		4F4ACFFF140996A10068A6D4 /* vstaudioeffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vstaudioeffect.cpp; sourceTree = "<group>"; };
+		4F4AD000140996A10068A6D4 /* vstaudioeffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstaudioeffect.h; sourceTree = "<group>"; };
+		4F4AD001140996A10068A6D4 /* vstbus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vstbus.cpp; sourceTree = "<group>"; };
+		4F4AD002140996A10068A6D4 /* vstbus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstbus.h; sourceTree = "<group>"; };
+		4F4AD003140996A10068A6D4 /* vstcomponent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vstcomponent.cpp; sourceTree = "<group>"; };
+		4F4AD004140996A10068A6D4 /* vstcomponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstcomponent.h; sourceTree = "<group>"; };
+		4F4AD005140996A10068A6D4 /* vstcomponentbase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vstcomponentbase.cpp; sourceTree = "<group>"; };
+		4F4AD006140996A10068A6D4 /* vstcomponentbase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstcomponentbase.h; sourceTree = "<group>"; };
+		4F4AD009140996A10068A6D4 /* vstinitiids.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vstinitiids.cpp; sourceTree = "<group>"; };
+		4F4AD00A140996A10068A6D4 /* vstnoteexpressiontypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vstnoteexpressiontypes.cpp; sourceTree = "<group>"; };
+		4F4AD00B140996A10068A6D4 /* vstnoteexpressiontypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstnoteexpressiontypes.h; sourceTree = "<group>"; };
+		4F4AD00C140996A10068A6D4 /* vstparameters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vstparameters.cpp; sourceTree = "<group>"; };
+		4F4AD00D140996A10068A6D4 /* vstparameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstparameters.h; sourceTree = "<group>"; };
+		4F4AD00E140996A10068A6D4 /* vstpresetfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vstpresetfile.cpp; sourceTree = "<group>"; };
+		4F4AD00F140996A10068A6D4 /* vstpresetfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstpresetfile.h; sourceTree = "<group>"; };
+		4F4AD010140996A10068A6D4 /* vstrepresentation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vstrepresentation.cpp; sourceTree = "<group>"; };
+		4F4AD011140996A10068A6D4 /* vstrepresentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstrepresentation.h; sourceTree = "<group>"; };
+		4F4AD012140996A10068A6D4 /* vstsinglecomponenteffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vstsinglecomponenteffect.cpp; sourceTree = "<group>"; };
+		4F4AD013140996A10068A6D4 /* vstsinglecomponenteffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstsinglecomponenteffect.h; sourceTree = "<group>"; };
+		4F4AD016140996A10068A6D4 /* conststringtable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conststringtable.cpp; sourceTree = "<group>"; };
+		4F4AD017140996A10068A6D4 /* conststringtable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conststringtable.h; sourceTree = "<group>"; };
+		4F4AD018140996A10068A6D4 /* falignpop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = falignpop.h; sourceTree = "<group>"; };
+		4F4AD019140996A10068A6D4 /* falignpush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = falignpush.h; sourceTree = "<group>"; };
+		4F4AD01A140996A10068A6D4 /* fplatform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fplatform.h; sourceTree = "<group>"; };
+		4F4AD01B140996A10068A6D4 /* fstrdefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fstrdefs.h; sourceTree = "<group>"; };
+		4F4AD01C140996A10068A6D4 /* ftypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ftypes.h; sourceTree = "<group>"; };
+		4F4AD01D140996A10068A6D4 /* funknown.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = funknown.cpp; sourceTree = "<group>"; };
+		4F4AD01E140996A10068A6D4 /* funknown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = funknown.h; sourceTree = "<group>"; };
+		4F4AD01F140996A10068A6D4 /* futils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = futils.h; sourceTree = "<group>"; };
+		4F4AD020140996A10068A6D4 /* ibstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ibstream.h; sourceTree = "<group>"; };
+		4F4AD021140996A10068A6D4 /* icloneable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = icloneable.h; sourceTree = "<group>"; };
+		4F4AD022140996A10068A6D4 /* ierrorcontext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ierrorcontext.h; sourceTree = "<group>"; };
+		4F4AD023140996A10068A6D4 /* ipersistent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ipersistent.h; sourceTree = "<group>"; };
+		4F4AD024140996A10068A6D4 /* ipluginbase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ipluginbase.h; sourceTree = "<group>"; };
+		4F4AD025140996A10068A6D4 /* istringresult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = istringresult.h; sourceTree = "<group>"; };
+		4F4AD026140996A10068A6D4 /* iupdatehandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iupdatehandler.h; sourceTree = "<group>"; };
+		4F4AD027140996A10068A6D4 /* keycodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keycodes.h; sourceTree = "<group>"; };
+		4F4AD028140996A10068A6D4 /* ustring.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ustring.cpp; sourceTree = "<group>"; };
+		4F4AD029140996A10068A6D4 /* ustring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ustring.h; sourceTree = "<group>"; };
+		4F4AD02B140996A10068A6D4 /* iplugview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iplugview.h; sourceTree = "<group>"; };
+		4F4AD02D140996A10068A6D4 /* ivstattributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivstattributes.h; sourceTree = "<group>"; };
+		4F4AD02E140996A10068A6D4 /* ivstaudioprocessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivstaudioprocessor.h; sourceTree = "<group>"; };
+		4F4AD02F140996A10068A6D4 /* ivstcomponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivstcomponent.h; sourceTree = "<group>"; };
+		4F4AD030140996A10068A6D4 /* ivstcontextmenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivstcontextmenu.h; sourceTree = "<group>"; };
+		4F4AD031140996A10068A6D4 /* ivsteditcontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivsteditcontroller.h; sourceTree = "<group>"; };
+		4F4AD032140996A10068A6D4 /* ivstevents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivstevents.h; sourceTree = "<group>"; };
+		4F4AD033140996A10068A6D4 /* ivsthostapplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivsthostapplication.h; sourceTree = "<group>"; };
+		4F4AD034140996A10068A6D4 /* ivstmessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivstmessage.h; sourceTree = "<group>"; };
+		4F4AD035140996A10068A6D4 /* ivstmidicontrollers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivstmidicontrollers.h; sourceTree = "<group>"; };
+		4F4AD036140996A10068A6D4 /* ivstnoteexpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivstnoteexpression.h; sourceTree = "<group>"; };
+		4F4AD037140996A10068A6D4 /* ivstparameterchanges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivstparameterchanges.h; sourceTree = "<group>"; };
+		4F4AD038140996A10068A6D4 /* ivstplugview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivstplugview.h; sourceTree = "<group>"; };
+		4F4AD039140996A10068A6D4 /* ivstprocesscontext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivstprocesscontext.h; sourceTree = "<group>"; };
+		4F4AD03A140996A10068A6D4 /* ivstrepresentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivstrepresentation.h; sourceTree = "<group>"; };
+		4F4AD03B140996A10068A6D4 /* ivstunits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ivstunits.h; sourceTree = "<group>"; };
+		4F4AD03C140996A10068A6D4 /* vstpresetkeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstpresetkeys.h; sourceTree = "<group>"; };
+		4F4AD03D140996A10068A6D4 /* vstpshpack4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstpshpack4.h; sourceTree = "<group>"; };
+		4F4AD03E140996A10068A6D4 /* vsttypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vsttypes.h; sourceTree = "<group>"; };
+		4F4AD1F11409A56A0068A6D4 /* base.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = base.xcodeproj; path = ../../VST3_SDK/base/mac/base.xcodeproj; sourceTree = SOURCE_ROOT; };
+		4F4CC3811549B8A700A9EA21 /* AccessiblePeakMeter-AAX-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "AccessiblePeakMeter-AAX-Info.plist"; path = "resources/AccessiblePeakMeter-AAX-Info.plist"; sourceTree = "<group>"; };
+		4F4CC38A1549B91100A9EA21 /* AAX_Exports.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AAX_Exports.cpp; path = ../../AAX_SDK/Interfaces/AAX_Exports.cpp; sourceTree = SOURCE_ROOT; };
+		4F4CC38C1549B92900A9EA21 /* CommonDebugSettings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = CommonDebugSettings.xcconfig; path = ../../AAX_SDK/ExamplePlugIns/Common/Mac/CommonDebugSettings.xcconfig; sourceTree = SOURCE_ROOT; };
+		4F4CC38D1549B92900A9EA21 /* CommonReleaseSettings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = CommonReleaseSettings.xcconfig; path = ../../AAX_SDK/ExamplePlugIns/Common/Mac/CommonReleaseSettings.xcconfig; sourceTree = SOURCE_ROOT; };
+		4F4CC4251549BED600A9EA21 /* IPlugAAX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugAAX.cpp; path = ../../WDL/IPlug/IPlugAAX.cpp; sourceTree = SOURCE_ROOT; };
+		4F4CC4261549BED600A9EA21 /* IPlugAAX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugAAX.h; path = ../../WDL/IPlug/IPlugAAX.h; sourceTree = SOURCE_ROOT; };
+		4F4CC4401549C15500A9EA21 /* IPlugAAX_Describe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugAAX_Describe.cpp; path = ../../WDL/IPlug/AAX/IPlugAAX_Describe.cpp; sourceTree = SOURCE_ROOT; };
+		4F4F73791576739300C124E3 /* AAX_CIPlugTaperDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AAX_CIPlugTaperDelegate.h; path = ../../WDL/IPlug/AAX/AAX_CIPlugTaperDelegate.h; sourceTree = SOURCE_ROOT; };
+		4F78D62313B637200032E0F3 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
+		4F78D7CF13B637790032E0F3 /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
+		4F78D89613B639100032E0F3 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = InfoPlist.strings; sourceTree = "<group>"; };
+		4F78D89813B639100032E0F3 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = MainMenu.xib; sourceTree = "<group>"; };
+		4F78D8BD13B63A4E0032E0F3 /* wdltypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wdltypes.h; path = ../../WDL/wdltypes.h; sourceTree = SOURCE_ROOT; };
+		4F78D8BF13B63A700032E0F3 /* RtAudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RtAudio.cpp; sourceTree = "<group>"; };
+		4F78D8C013B63A700032E0F3 /* RtAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RtAudio.h; sourceTree = "<group>"; };
+		4F78D8C113B63A700032E0F3 /* RtError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RtError.h; sourceTree = "<group>"; };
+		4F78D8C213B63A700032E0F3 /* RtMidi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RtMidi.cpp; sourceTree = "<group>"; };
+		4F78D8C313B63A700032E0F3 /* RtMidi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RtMidi.h; sourceTree = "<group>"; };
+		4F78D8D213B63B5D0032E0F3 /* aeffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aeffect.h; sourceTree = "<group>"; };
+		4F78D8D313B63B5D0032E0F3 /* aeffectx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aeffectx.h; sourceTree = "<group>"; };
+		4F78D8E613B63BA40032E0F3 /* IPlug_include_in_plug_hdr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlug_include_in_plug_hdr.h; path = ../../WDL/IPlug/IPlug_include_in_plug_hdr.h; sourceTree = SOURCE_ROOT; };
+		4F78D8E813B63BA40032E0F3 /* IPlug_include_in_plug_src.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlug_include_in_plug_src.h; path = ../../WDL/IPlug/IPlug_include_in_plug_src.h; sourceTree = SOURCE_ROOT; };
+		4F78D8E913B63BA40032E0F3 /* IControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IControl.h; path = ../../WDL/IPlug/IControl.h; sourceTree = SOURCE_ROOT; };
+		4F78D8EA13B63BA40032E0F3 /* IKeyboardControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IKeyboardControl.h; path = ../../WDL/IPlug/IKeyboardControl.h; sourceTree = SOURCE_ROOT; };
+		4F78D8EB13B63BA40032E0F3 /* IPlugStandalone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugStandalone.cpp; path = ../../WDL/IPlug/IPlugStandalone.cpp; sourceTree = SOURCE_ROOT; };
+		4F78D8EC13B63BA40032E0F3 /* IPlugBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugBase.h; path = ../../WDL/IPlug/IPlugBase.h; sourceTree = SOURCE_ROOT; };
+		4F78D8ED13B63BA40032E0F3 /* IPlugBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugBase.cpp; path = ../../WDL/IPlug/IPlugBase.cpp; sourceTree = SOURCE_ROOT; };
+		4F78D8EE13B63BA50032E0F3 /* IGraphicsMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IGraphicsMac.h; path = ../../WDL/IPlug/IGraphicsMac.h; sourceTree = SOURCE_ROOT; };
+		4F78D8EF13B63BA50032E0F3 /* IPlugStructs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugStructs.cpp; path = ../../WDL/IPlug/IPlugStructs.cpp; sourceTree = SOURCE_ROOT; };
+		4F78D8F113B63BA50032E0F3 /* Containers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Containers.h; path = ../../WDL/IPlug/Containers.h; sourceTree = SOURCE_ROOT; };
+		4F78D8F213B63BA50032E0F3 /* Hosts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Hosts.h; path = ../../WDL/IPlug/Hosts.h; sourceTree = SOURCE_ROOT; };
+		4F78D8F313B63BA50032E0F3 /* Hosts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Hosts.cpp; path = ../../WDL/IPlug/Hosts.cpp; sourceTree = SOURCE_ROOT; };
+		4F78D8F513B63BA50032E0F3 /* IGraphicsMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = IGraphicsMac.mm; path = ../../WDL/IPlug/IGraphicsMac.mm; sourceTree = SOURCE_ROOT; };
+		4F78D8F613B63BA50032E0F3 /* IGraphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IGraphics.cpp; path = ../../WDL/IPlug/IGraphics.cpp; sourceTree = SOURCE_ROOT; };
+		4F78D8F713B63BA50032E0F3 /* IGraphicsCarbon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IGraphicsCarbon.cpp; path = ../../WDL/IPlug/IGraphicsCarbon.cpp; sourceTree = SOURCE_ROOT; };
+		4F78D8F813B63BA50032E0F3 /* IGraphicsCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = IGraphicsCocoa.mm; path = ../../WDL/IPlug/IGraphicsCocoa.mm; sourceTree = SOURCE_ROOT; };
+		4F78D8F913B63BA50032E0F3 /* IGraphicsCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IGraphicsCocoa.h; path = ../../WDL/IPlug/IGraphicsCocoa.h; sourceTree = SOURCE_ROOT; };
+		4F78D8FA13B63BA50032E0F3 /* Log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Log.h; path = ../../WDL/IPlug/Log.h; sourceTree = SOURCE_ROOT; };
+		4F78D8FB13B63BA50032E0F3 /* Log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Log.cpp; path = ../../WDL/IPlug/Log.cpp; sourceTree = SOURCE_ROOT; };
+		4F78D8FC13B63BA50032E0F3 /* IPopupMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPopupMenu.h; path = ../../WDL/IPlug/IPopupMenu.h; sourceTree = SOURCE_ROOT; };
+		4F78D8FD13B63BA50032E0F3 /* IPopupMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPopupMenu.cpp; path = ../../WDL/IPlug/IPopupMenu.cpp; sourceTree = SOURCE_ROOT; };
+		4F78D8FE13B63BA50032E0F3 /* IPlugStructs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugStructs.h; path = ../../WDL/IPlug/IPlugStructs.h; sourceTree = SOURCE_ROOT; };
+		4F78D90213B63BA50032E0F3 /* IPlug_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlug_Prefix.pch; path = ../../WDL/IPlug/IPlug_Prefix.pch; sourceTree = SOURCE_ROOT; };
+		4F78D90313B63BA50032E0F3 /* IParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IParam.h; path = ../../WDL/IPlug/IParam.h; sourceTree = SOURCE_ROOT; };
+		4F78D90413B63BA50032E0F3 /* IParam.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IParam.cpp; path = ../../WDL/IPlug/IParam.cpp; sourceTree = SOURCE_ROOT; };
+		4F78D90513B63BA50032E0F3 /* IMidiQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IMidiQueue.h; path = ../../WDL/IPlug/IMidiQueue.h; sourceTree = SOURCE_ROOT; };
+		4F78D90713B63BA50032E0F3 /* IGraphicsCarbon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IGraphicsCarbon.h; path = ../../WDL/IPlug/IGraphicsCarbon.h; sourceTree = SOURCE_ROOT; };
+		4F78D90813B63BA50032E0F3 /* IGraphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IGraphics.h; path = ../../WDL/IPlug/IGraphics.h; sourceTree = SOURCE_ROOT; };
+		4F78D90913B63BA50032E0F3 /* IControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IControl.cpp; path = ../../WDL/IPlug/IControl.cpp; sourceTree = SOURCE_ROOT; };
+		4F78D9EA13B63BE90032E0F3 /* IPlugStandalone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugStandalone.h; path = ../../WDL/IPlug/IPlugStandalone.h; sourceTree = SOURCE_ROOT; };
+		4F78D9EC13B63C6A0032E0F3 /* IPlugVST.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugVST.cpp; path = ../../WDL/IPlug/IPlugVST.cpp; sourceTree = SOURCE_ROOT; };
+		4F78D9ED13B63C6A0032E0F3 /* IPlugVST.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugVST.h; path = ../../WDL/IPlug/IPlugVST.h; sourceTree = SOURCE_ROOT; };
+		4F78D9FB13B63CD90032E0F3 /* IPlugAU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugAU.h; path = ../../WDL/IPlug/IPlugAU.h; sourceTree = SOURCE_ROOT; };
+		4F78D9FC13B63CD90032E0F3 /* IPlugAU.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugAU.cpp; path = ../../WDL/IPlug/IPlugAU.cpp; sourceTree = SOURCE_ROOT; };
+		4F78D9FD13B63CD90032E0F3 /* IPlugAU.r */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.rez; name = IPlugAU.r; path = ../../WDL/IPlug/IPlugAU.r; sourceTree = SOURCE_ROOT; };
+		4F78D9FE13B63CD90032E0F3 /* IPlugAU_ViewFactory.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = IPlugAU_ViewFactory.mm; path = ../../WDL/IPlug/IPlugAU_ViewFactory.mm; sourceTree = SOURCE_ROOT; };
+		4F78DAEA13B642790032E0F3 /* IGraphicsWin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IGraphicsWin.cpp; path = ../../WDL/IPlug/IGraphicsWin.cpp; sourceTree = SOURCE_ROOT; };
+		4F78DAEB13B642790032E0F3 /* IGraphicsWin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IGraphicsWin.h; path = ../../WDL/IPlug/IGraphicsWin.h; sourceTree = SOURCE_ROOT; };
+		4F78DB5F13B6462B0032E0F3 /* AccessiblePeakMeter.component */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AccessiblePeakMeter.component; sourceTree = BUILT_PRODUCTS_DIR; };
+		4F79A34C146304CD00744AED /* IPlugProcessAS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugProcessAS.cpp; path = ../../WDL/IPlug/RTAS/IPlugProcessAS.cpp; sourceTree = "<group>"; };
+		4F79A34D146304CD00744AED /* IPlugProcessAS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugProcessAS.h; path = ../../WDL/IPlug/RTAS/IPlugProcessAS.h; sourceTree = "<group>"; };
+		4F7E1EB116792F6000907FCF /* bg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = bg.png; path = resources/img/bg.png; sourceTree = "<group>"; };
+		4F7F5C0C13E95DDC002918FD /* AccessiblePeakMeter-RTAS-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "AccessiblePeakMeter-RTAS-Info.plist"; path = "resources/AccessiblePeakMeter-RTAS-Info.plist"; sourceTree = "<group>"; };
+		4F7F5C6813E95EC8002918FD /* AccessiblePeakMeter.dpm */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AccessiblePeakMeter.dpm; sourceTree = BUILT_PRODUCTS_DIR; };
+		4F7F5C6F13E95FB2002918FD /* IPlugRTAS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugRTAS.cpp; path = ../../WDL/IPlug/IPlugRTAS.cpp; sourceTree = SOURCE_ROOT; };
+		4F7F5C7013E95FB2002918FD /* IPlugRTAS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugRTAS.h; path = ../../WDL/IPlug/IPlugRTAS.h; sourceTree = SOURCE_ROOT; };
+		4F7F5C9B13E9607A002918FD /* digicode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = digicode.h; path = ../../WDL/IPlug/RTAS/digicode.h; sourceTree = "<group>"; };
+		4F7F5C9C13E9607A002918FD /* digicode1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = digicode1.cpp; path = ../../WDL/IPlug/RTAS/digicode1.cpp; sourceTree = "<group>"; };
+		4F7F5C9D13E9607A002918FD /* digicode2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = digicode2.cpp; path = ../../WDL/IPlug/RTAS/digicode2.cpp; sourceTree = "<group>"; };
+		4F7F5C9E13E9607A002918FD /* digicode3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = digicode3.cpp; path = ../../WDL/IPlug/RTAS/digicode3.cpp; sourceTree = "<group>"; };
+		4F7F5C9F13E9607A002918FD /* EditorInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditorInterface.h; path = ../../WDL/IPlug/RTAS/EditorInterface.h; sourceTree = "<group>"; };
+		4F7F5CA013E9607A002918FD /* IPlugCustomUI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugCustomUI.cpp; path = ../../WDL/IPlug/RTAS/IPlugCustomUI.cpp; sourceTree = "<group>"; };
+		4F7F5CA113E9607A002918FD /* IPlugCustomUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugCustomUI.h; path = ../../WDL/IPlug/RTAS/IPlugCustomUI.h; sourceTree = "<group>"; };
+		4F7F5CA213E9607A002918FD /* IPlugDigiView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugDigiView.h; path = ../../WDL/IPlug/RTAS/IPlugDigiView.h; sourceTree = "<group>"; };
+		4F7F5CA313E9607A002918FD /* IPlugGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugGroup.cpp; path = ../../WDL/IPlug/RTAS/IPlugGroup.cpp; sourceTree = "<group>"; };
+		4F7F5CA413E9607A002918FD /* IPlugGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugGroup.h; path = ../../WDL/IPlug/RTAS/IPlugGroup.h; sourceTree = "<group>"; };
+		4F7F5CA513E9607A002918FD /* IPlugProcess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugProcess.cpp; path = ../../WDL/IPlug/RTAS/IPlugProcess.cpp; sourceTree = "<group>"; };
+		4F7F5CA613E9607A002918FD /* IPlugProcess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugProcess.h; path = ../../WDL/IPlug/RTAS/IPlugProcess.h; sourceTree = "<group>"; };
+		4F7F5CA713E9607A002918FD /* IPlugProcessRTAS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IPlugProcessRTAS.cpp; path = ../../WDL/IPlug/RTAS/IPlugProcessRTAS.cpp; sourceTree = "<group>"; };
+		4F7F5CA813E9607A002918FD /* IPlugProcessRTAS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IPlugProcessRTAS.h; path = ../../WDL/IPlug/RTAS/IPlugProcessRTAS.h; sourceTree = "<group>"; };
+		4F7F5CAA13E9607A002918FD /* ProcessInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProcessInterface.h; path = ../../WDL/IPlug/RTAS/ProcessInterface.h; sourceTree = "<group>"; };
+		4F7F5CAB13E9607A002918FD /* CommonDebugSettings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = CommonDebugSettings.xcconfig; path = ../../PT9_SDK/AlturaPorts/TDMPlugIns/common/Mac/CommonDebugSettings.xcconfig; sourceTree = SOURCE_ROOT; };
+		4F7F5CAC13E9607A002918FD /* CommonReleaseSettings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = CommonReleaseSettings.xcconfig; path = ../../PT9_SDK/AlturaPorts/TDMPlugIns/common/Mac/CommonReleaseSettings.xcconfig; sourceTree = SOURCE_ROOT; };
+		4F7F5CF613E96564002918FD /* System.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = System.framework; path = /System/Library/Frameworks/System.framework; sourceTree = "<absolute>"; };
+		4F7F5D2413E9681E002918FD /* IPlugRTAS.r */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.rez; name = IPlugRTAS.r; path = ../../WDL/IPlug/RTAS/IPlugRTAS.r; sourceTree = "<group>"; };
+		4F8B6747158B4F53002FC25B /* PluginLibrary.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = PluginLibrary.xcodeproj; path = ../../PT9_SDK/AlturaPorts/TDMPlugIns/PlugInLibrary/MacBuild/PluginLibrary.xcodeproj; sourceTree = SOURCE_ROOT; };
+		4F8D4BC413E97664004F7633 /* lice.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = lice.xcodeproj; path = ../../WDL/lice/lice.xcodeproj; sourceTree = SOURCE_ROOT; };
+		4F9828E0140A9EB700F3FCC1 /* AccessiblePeakMeter.vst3 */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AccessiblePeakMeter.vst3; sourceTree = BUILT_PRODUCTS_DIR; };
+		4FA88B901444E4C4006CB8DA /* dfx-au-utilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "dfx-au-utilities.c"; path = "../../WDL/IPlug/dfx/dfx-au-utilities.c"; sourceTree = SOURCE_ROOT; };
+		4FA88B911444E4C4006CB8DA /* dfx-au-utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "dfx-au-utilities.h"; path = "../../WDL/IPlug/dfx/dfx-au-utilities.h"; sourceTree = SOURCE_ROOT; };
+		4FB3624E13B648FE00DB6B76 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = main.mm; path = app_wrapper/main.mm; sourceTree = "<group>"; };
+		4FB600331567CB0A0020189A /* AccessiblePeakMeter.aaxplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AccessiblePeakMeter.aaxplugin; sourceTree = BUILT_PRODUCTS_DIR; };
+		4FCF15AF133124D1009A6277 /* AccessiblePeakMeter.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = AccessiblePeakMeter.xcconfig; sourceTree = "<group>"; };
+		4FD16A0913B63081001D0217 /* AccessiblePeakMeter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AccessiblePeakMeter.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		4FD16C9E13B6327C001D0217 /* app_resource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = app_resource.h; path = app_wrapper/app_resource.h; sourceTree = "<group>"; };
+		4FD16C9F13B6327C001D0217 /* app_main.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = app_main.h; path = app_wrapper/app_main.h; sourceTree = "<group>"; };
+		4FD16CA013B6327C001D0217 /* app_main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = app_main.cpp; path = app_wrapper/app_main.cpp; sourceTree = "<group>"; };
+		4FD16CA113B6327C001D0217 /* app_dialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = app_dialog.cpp; path = app_wrapper/app_dialog.cpp; sourceTree = "<group>"; };
+		4FD16CFB13B63468001D0217 /* swell-appstub.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-appstub.mm"; path = "../../WDL/swell/swell-appstub.mm"; sourceTree = SOURCE_ROOT; };
+		4FD16D0213B63489001D0217 /* swell-menugen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "swell-menugen.h"; path = "../../WDL/swell/swell-menugen.h"; sourceTree = SOURCE_ROOT; };
+		4FD16D0313B63494001D0217 /* swell-dlggen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "swell-dlggen.h"; path = "../../WDL/swell/swell-dlggen.h"; sourceTree = SOURCE_ROOT; };
+		4FD16D0413B634AA001D0217 /* swell-dlg.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-dlg.mm"; path = "../../WDL/swell/swell-dlg.mm"; sourceTree = SOURCE_ROOT; };
+		4FD16D0B13B634BF001D0217 /* swell-gdi.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-gdi.mm"; path = "../../WDL/swell/swell-gdi.mm"; sourceTree = SOURCE_ROOT; };
+		4FD16D1513B634D2001D0217 /* swell-ini.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "swell-ini.cpp"; path = "../../WDL/swell/swell-ini.cpp"; sourceTree = SOURCE_ROOT; };
+		4FD16D1713B634E5001D0217 /* swell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = swell.h; path = ../../WDL/swell/swell.h; sourceTree = SOURCE_ROOT; };
+		4FD16D2213B6351C001D0217 /* swell-functions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "swell-functions.h"; path = "../../WDL/swell/swell-functions.h"; sourceTree = SOURCE_ROOT; };
+		4FD16D2B13B6353C001D0217 /* swell-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "swell-internal.h"; path = "../../WDL/swell/swell-internal.h"; sourceTree = SOURCE_ROOT; };
+		4FD16D3013B6355A001D0217 /* swell-types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "swell-types.h"; path = "../../WDL/swell/swell-types.h"; sourceTree = SOURCE_ROOT; };
+		4FD16D3913B63582001D0217 /* swell-kb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-kb.mm"; path = "../../WDL/swell/swell-kb.mm"; sourceTree = SOURCE_ROOT; };
+		4FD16D3B13B6358C001D0217 /* swell-miscdlg.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-miscdlg.mm"; path = "../../WDL/swell/swell-miscdlg.mm"; sourceTree = SOURCE_ROOT; };
+		4FD16D3D13B63595001D0217 /* swell-menu.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-menu.mm"; path = "../../WDL/swell/swell-menu.mm"; sourceTree = SOURCE_ROOT; };
+		4FD16D3F13B635A0001D0217 /* swell-misc.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-misc.mm"; path = "../../WDL/swell/swell-misc.mm"; sourceTree = SOURCE_ROOT; };
+		4FD16D4113B635AB001D0217 /* swell-wnd.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-wnd.mm"; path = "../../WDL/swell/swell-wnd.mm"; sourceTree = SOURCE_ROOT; };
+		4FD16D4313B635B2001D0217 /* swell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = swell.cpp; path = ../../WDL/swell/swell.cpp; sourceTree = SOURCE_ROOT; };
+		4FD16D4513B635C8001D0217 /* swellappmain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = swellappmain.h; path = ../../WDL/swell/swellappmain.h; sourceTree = SOURCE_ROOT; };
+		4FD16D4613B635C8001D0217 /* swellappmain.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = swellappmain.mm; path = ../../WDL/swell/swellappmain.mm; sourceTree = SOURCE_ROOT; };
+		4FD290A8137C34D700CEBE7E /* AccessiblePeakMeter.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = AccessiblePeakMeter.icns; path = resources/AccessiblePeakMeter.icns; sourceTree = "<group>"; };
+		4FDA440513F3E4F2000B4551 /* IBitmapMonoText.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IBitmapMonoText.cpp; path = ../../WDL/IPlug/IBitmapMonoText.cpp; sourceTree = SOURCE_ROOT; };
+		4FDA440613F3E4F2000B4551 /* IBitmapMonoText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IBitmapMonoText.h; path = ../../WDL/IPlug/IBitmapMonoText.h; sourceTree = SOURCE_ROOT; };
+		4FF016F4134E14E2001447BA /* mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mutex.h; path = ../../WDL/mutex.h; sourceTree = SOURCE_ROOT; };
+		4FF016F5134E14E2001447BA /* ptrlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ptrlist.h; path = ../../WDL/ptrlist.h; sourceTree = SOURCE_ROOT; };
+		4FF016F6134E14E2001447BA /* wdlstring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wdlstring.h; path = ../../WDL/wdlstring.h; sourceTree = SOURCE_ROOT; };
+		4FF01719134E153A001447BA /* heapbuf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = heapbuf.h; path = ../../WDL/heapbuf.h; sourceTree = SOURCE_ROOT; };
+		4FF7B0D4156A825000E6CB12 /* common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = common.xcconfig; path = ../../common.xcconfig; sourceTree = SOURCE_ROOT; };
+		4FF7B0F3156A831000E6CB12 /* AAXLibrary.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AAXLibrary.xcodeproj; path = ../../AAX_SDK/Libs/AAXLibrary/MacBuild/AAXLibrary.xcodeproj; sourceTree = SOURCE_ROOT; };
+		526F9C010D7DC7D700562CF8 /* AccessiblePeakMeter.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; path = AccessiblePeakMeter.exp; sourceTree = "<group>"; };
+		52C4DB180D0E51270007A920 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
+		52E41CB90D14C2A900A0943B /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
+		52E41CC40D14C2B000A0943B /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; };
+		52E41D7E0D14C2D100A0943B /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = "<absolute>"; };
+		52E41D920D14C2D600A0943B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; };
+		52FBBED00D0CF139001C8B8A /* AccessiblePeakMeter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = AccessiblePeakMeter.cpp; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
+		52FBBED20D0CF13D001C8B8A /* AccessiblePeakMeter.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = AccessiblePeakMeter.h; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
+		52FBBED30D0CF143001C8B8A /* resource.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = resource.h; sourceTree = "<group>"; tabWidth = 2; usesTabs = 0; };
+		5EDC2A771A93B020004EFD46 /* ADSR.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADSR.h; sourceTree = "<group>"; };
+		5EDC2A781A93B020004EFD46 /* Envelope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Envelope.h; sourceTree = "<group>"; };
+		5EDC2A791A93B020004EFD46 /* Generator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Generator.h; sourceTree = "<group>"; };
+		5EDC2A7A1A93B020004EFD46 /* SineWave.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SineWave.h; sourceTree = "<group>"; };
+		5EDC2A7B1A93B020004EFD46 /* Stk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Stk.h; sourceTree = "<group>"; };
+		5EDC2A7D1A93B020004EFD46 /* ADSR.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ADSR.cpp; sourceTree = "<group>"; };
+		5EDC2A7E1A93B020004EFD46 /* Envelope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Envelope.cpp; sourceTree = "<group>"; };
+		5EDC2A7F1A93B020004EFD46 /* SineWave.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SineWave.cpp; sourceTree = "<group>"; };
+		5EDC2A801A93B020004EFD46 /* Stk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Stk.cpp; sourceTree = "<group>"; };
+		5EDC2A921A93B337004EFD46 /* fader.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fader.png; path = resources/img/fader.png; sourceTree = "<group>"; };
+		5EDC2A951A93B343004EFD46 /* switch.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = switch.png; path = resources/img/switch.png; sourceTree = "<group>"; };
+		D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		4F20EF2C132C69FE0030E34C /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F8D4C2F13E97806004F7633 /* lice.a in Frameworks */,
+				4F20EF2D132C69FE0030E34C /* Cocoa.framework in Frameworks */,
+				4F20EF2E132C69FE0030E34C /* Carbon.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4F3AE1D312C0E5E2001FD7A4 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F8D4C2813E9778D004F7633 /* lice.a in Frameworks */,
+				4F3AE1D412C0E5E2001FD7A4 /* Carbon.framework in Frameworks */,
+				4F3AE1D512C0E5E2001FD7A4 /* Cocoa.framework in Frameworks */,
+				4F3AE1D612C0E5E2001FD7A4 /* AudioToolbox.framework in Frameworks */,
+				4F3AE1D712C0E5E2001FD7A4 /* AudioUnit.framework in Frameworks */,
+				4F3AE1D812C0E5E2001FD7A4 /* CoreServices.framework in Frameworks */,
+				4F3AE1D912C0E5E2001FD7A4 /* CoreAudio.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4F7F5C5F13E95EC8002918FD /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F8B6766158B4F74002FC25B /* libPluginLibrary.a in Frameworks */,
+				4F8D4C2913E97794004F7633 /* lice32.a in Frameworks */,
+				4F7F5C6213E95EC8002918FD /* Cocoa.framework in Frameworks */,
+				4F7F5C6313E95EC8002918FD /* Carbon.framework in Frameworks */,
+				4F7F5CF713E96564002918FD /* System.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4F9828D7140A9EB700F3FCC1 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F9828F6140A9EEE00F3FCC1 /* lice.a in Frameworks */,
+				4F9828D8140A9EB700F3FCC1 /* libbase.a in Frameworks */,
+				4F9828DA140A9EB700F3FCC1 /* Cocoa.framework in Frameworks */,
+				4F9828DB140A9EB700F3FCC1 /* Carbon.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4FB6002A1567CB0A0020189A /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F3B0B44158B50A5001B0CEF /* libAAXLibrary.a in Frameworks */,
+				4FB600551567CBF90020189A /* lice.a in Frameworks */,
+				4FB6002C1567CB0A0020189A /* Cocoa.framework in Frameworks */,
+				4FB6002D1567CB0A0020189A /* Carbon.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4FD16A0713B63081001D0217 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F8D4BCD13E97671004F7633 /* lice.a in Frameworks */,
+				4F78D87513B637E50032E0F3 /* Carbon.framework in Frameworks */,
+				4F78D7D013B637790032E0F3 /* CoreMIDI.framework in Frameworks */,
+				4F78D70B13B637340032E0F3 /* CoreFoundation.framework in Frameworks */,
+				4F78D86E13B637A20032E0F3 /* CoreData.framework in Frameworks */,
+				4F78D87013B637A20032E0F3 /* CoreAudio.framework in Frameworks */,
+				4F78D87113B637A20032E0F3 /* Cocoa.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		089C166AFE841209C02AAC07 /* IPlugExample */ = {
+			isa = PBXGroup;
+			children = (
+				5EDC2A751A93B020004EFD46 /* stk */,
+				52FBBED30D0CF143001C8B8A /* resource.h */,
+				52FBBED20D0CF13D001C8B8A /* AccessiblePeakMeter.h */,
+				52FBBED00D0CF139001C8B8A /* AccessiblePeakMeter.cpp */,
+				089C167CFE841241C02AAC07 /* Resources */,
+				32C88E010371C26100C91783 /* Other Sources */,
+				089C1671FE841209C02AAC07 /* Frameworks and Libraries */,
+				19C28FB8FE9D52D311CA2CBB /* Products */,
+			);
+			name = IPlugExample;
+			sourceTree = "<group>";
+		};
+		089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = {
+			isa = PBXGroup;
+			children = (
+				4FF01613134E0BCD001447BA /* WDL */,
+				1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */,
+			);
+			name = "Frameworks and Libraries";
+			sourceTree = "<group>";
+		};
+		089C167CFE841241C02AAC07 /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				4FD16A0213B6303B001D0217 /* img */,
+				4F23BA1413B647E50097A67E /* AccessiblePeakMeter-OSXAPP-Info.plist */,
+				4F23BA1513B647E50097A67E /* AccessiblePeakMeter-VST2-Info.plist */,
+				4F3E693A1409747300C4D749 /* AccessiblePeakMeter-VST3-Info.plist */,
+				4F23BA1313B647E50097A67E /* AccessiblePeakMeter-AU-Info.plist */,
+				4F7F5C0C13E95DDC002918FD /* AccessiblePeakMeter-RTAS-Info.plist */,
+				4F4CC3811549B8A700A9EA21 /* AccessiblePeakMeter-AAX-Info.plist */,
+				4FD290A8137C34D700CEBE7E /* AccessiblePeakMeter.icns */,
+			);
+			name = Resources;
+			sourceTree = "<group>";
+		};
+		1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				4F78DB2113B644E80032E0F3 /* App & Plugins */,
+				4F3E695B1409774100C4D749 /* VST3 Plugin */,
+				4F78DB2213B645060032E0F3 /* AU Plugin */,
+				4F7F5CEB13E9651F002918FD /* RTAS Plugin */,
+				4F05224015656DAD00AE0D2E /* AAX Plugin */,
+				4F78DB2013B644BD0032E0F3 /* App */,
+			);
+			name = "Linked Frameworks";
+			sourceTree = "<group>";
+		};
+		19C28FB8FE9D52D311CA2CBB /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				4FD16A0913B63081001D0217 /* AccessiblePeakMeter.app */,
+				4F20EF33132C69FE0030E34C /* AccessiblePeakMeter.vst */,
+				4F9828E0140A9EB700F3FCC1 /* AccessiblePeakMeter.vst3 */,
+				4F78DB5F13B6462B0032E0F3 /* AccessiblePeakMeter.component */,
+				4F7F5C6813E95EC8002918FD /* AccessiblePeakMeter.dpm */,
+				4FB600331567CB0A0020189A /* AccessiblePeakMeter.aaxplugin */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		32C88E010371C26100C91783 /* Other Sources */ = {
+			isa = PBXGroup;
+			children = (
+				4FD16C9D13B6327C001D0217 /* OSX App Wrapper */,
+				526F9C010D7DC7D700562CF8 /* AccessiblePeakMeter.exp */,
+				4FCF15AF133124D1009A6277 /* AccessiblePeakMeter.xcconfig */,
+				4FF7B0D4156A825000E6CB12 /* common.xcconfig */,
+			);
+			name = "Other Sources";
+			sourceTree = "<group>";
+		};
+		4F05224015656DAD00AE0D2E /* AAX Plugin */ = {
+			isa = PBXGroup;
+			children = (
+				4FF7B0F3156A831000E6CB12 /* AAXLibrary.xcodeproj */,
+			);
+			name = "AAX Plugin";
+			sourceTree = "<group>";
+		};
+		4F24EE731567A674006B889A /* RTAS_SDK */ = {
+			isa = PBXGroup;
+			children = (
+				4F7F5CAB13E9607A002918FD /* CommonDebugSettings.xcconfig */,
+				4F7F5CAC13E9607A002918FD /* CommonReleaseSettings.xcconfig */,
+				4F7F5C9B13E9607A002918FD /* digicode.h */,
+				4F7F5C9C13E9607A002918FD /* digicode1.cpp */,
+				4F7F5C9D13E9607A002918FD /* digicode2.cpp */,
+				4F7F5C9E13E9607A002918FD /* digicode3.cpp */,
+			);
+			name = RTAS_SDK;
+			sourceTree = "<group>";
+		};
+		4F24EE751567A6A6006B889A /* AAX_SDK */ = {
+			isa = PBXGroup;
+			children = (
+				4F4CC38C1549B92900A9EA21 /* CommonDebugSettings.xcconfig */,
+				4F4CC38D1549B92900A9EA21 /* CommonReleaseSettings.xcconfig */,
+				4F4CC38A1549B91100A9EA21 /* AAX_Exports.cpp */,
+			);
+			name = AAX_SDK;
+			sourceTree = "<group>";
+		};
+		4F3E69001409743C00C4D749 /* VST3 */ = {
+			isa = PBXGroup;
+			children = (
+				4F3E69041409746500C4D749 /* IPlugVST3.cpp */,
+				4F3E69051409746500C4D749 /* IPlugVST3.h */,
+			);
+			name = VST3;
+			sourceTree = "<group>";
+		};
+		4F3E695B1409774100C4D749 /* VST3 Plugin */ = {
+			isa = PBXGroup;
+			children = (
+				4F4AD1F11409A56A0068A6D4 /* base.xcodeproj */,
+			);
+			name = "VST3 Plugin";
+			sourceTree = "<group>";
+		};
+		4F3E696A1409778C00C4D749 /* VST3_SDK */ = {
+			isa = PBXGroup;
+			children = (
+				4F4ACFF2140996A10068A6D4 /* public.sdk */,
+				4F4AD014140996A10068A6D4 /* pluginterfaces */,
+			);
+			name = VST3_SDK;
+			sourceTree = "<group>";
+		};
+		4F4ACFF2140996A10068A6D4 /* public.sdk */ = {
+			isa = PBXGroup;
+			children = (
+				4F4ACFF3140996A10068A6D4 /* source */,
+			);
+			name = public.sdk;
+			path = ../../VST3_SDK/public.sdk;
+			sourceTree = SOURCE_ROOT;
+		};
+		4F4ACFF3140996A10068A6D4 /* source */ = {
+			isa = PBXGroup;
+			children = (
+				4F4ACFF4140996A10068A6D4 /* common */,
+				4F4ACFF9140996A10068A6D4 /* main */,
+				4F4ACFFE140996A10068A6D4 /* vst */,
+			);
+			path = source;
+			sourceTree = "<group>";
+		};
+		4F4ACFF4140996A10068A6D4 /* common */ = {
+			isa = PBXGroup;
+			children = (
+				4F4ACFF5140996A10068A6D4 /* memorystream.cpp */,
+				4F4ACFF6140996A10068A6D4 /* memorystream.h */,
+				4F4ACFF7140996A10068A6D4 /* pluginview.cpp */,
+				4F4ACFF8140996A10068A6D4 /* pluginview.h */,
+			);
+			path = common;
+			sourceTree = "<group>";
+		};
+		4F4ACFF9140996A10068A6D4 /* main */ = {
+			isa = PBXGroup;
+			children = (
+				4F4ACFFB140996A10068A6D4 /* macmain.cpp */,
+				4F4ACFFC140996A10068A6D4 /* pluginfactoryvst3.cpp */,
+				4F4ACFFD140996A10068A6D4 /* pluginfactoryvst3.h */,
+			);
+			path = main;
+			sourceTree = "<group>";
+		};
+		4F4ACFFE140996A10068A6D4 /* vst */ = {
+			isa = PBXGroup;
+			children = (
+				4F4ACFFF140996A10068A6D4 /* vstaudioeffect.cpp */,
+				4F4AD000140996A10068A6D4 /* vstaudioeffect.h */,
+				4F4AD001140996A10068A6D4 /* vstbus.cpp */,
+				4F4AD002140996A10068A6D4 /* vstbus.h */,
+				4F4AD003140996A10068A6D4 /* vstcomponent.cpp */,
+				4F4AD004140996A10068A6D4 /* vstcomponent.h */,
+				4F4AD005140996A10068A6D4 /* vstcomponentbase.cpp */,
+				4F4AD006140996A10068A6D4 /* vstcomponentbase.h */,
+				4F4AD009140996A10068A6D4 /* vstinitiids.cpp */,
+				4F4AD00A140996A10068A6D4 /* vstnoteexpressiontypes.cpp */,
+				4F4AD00B140996A10068A6D4 /* vstnoteexpressiontypes.h */,
+				4F4AD00C140996A10068A6D4 /* vstparameters.cpp */,
+				4F4AD00D140996A10068A6D4 /* vstparameters.h */,
+				4F4AD00E140996A10068A6D4 /* vstpresetfile.cpp */,
+				4F4AD00F140996A10068A6D4 /* vstpresetfile.h */,
+				4F4AD010140996A10068A6D4 /* vstrepresentation.cpp */,
+				4F4AD011140996A10068A6D4 /* vstrepresentation.h */,
+				4F4AD012140996A10068A6D4 /* vstsinglecomponenteffect.cpp */,
+				4F4AD013140996A10068A6D4 /* vstsinglecomponenteffect.h */,
+			);
+			path = vst;
+			sourceTree = "<group>";
+		};
+		4F4AD014140996A10068A6D4 /* pluginterfaces */ = {
+			isa = PBXGroup;
+			children = (
+				4F4AD015140996A10068A6D4 /* base */,
+				4F4AD02A140996A10068A6D4 /* gui */,
+				4F4AD02C140996A10068A6D4 /* vst */,
+			);
+			name = pluginterfaces;
+			path = ../../VST3_SDK/pluginterfaces;
+			sourceTree = SOURCE_ROOT;
+		};
+		4F4AD015140996A10068A6D4 /* base */ = {
+			isa = PBXGroup;
+			children = (
+				4F4AD016140996A10068A6D4 /* conststringtable.cpp */,
+				4F4AD017140996A10068A6D4 /* conststringtable.h */,
+				4F4AD018140996A10068A6D4 /* falignpop.h */,
+				4F4AD019140996A10068A6D4 /* falignpush.h */,
+				4F4AD01A140996A10068A6D4 /* fplatform.h */,
+				4F4AD01B140996A10068A6D4 /* fstrdefs.h */,
+				4F4AD01C140996A10068A6D4 /* ftypes.h */,
+				4F4AD01D140996A10068A6D4 /* funknown.cpp */,
+				4F4AD01E140996A10068A6D4 /* funknown.h */,
+				4F4AD01F140996A10068A6D4 /* futils.h */,
+				4F4AD020140996A10068A6D4 /* ibstream.h */,
+				4F4AD021140996A10068A6D4 /* icloneable.h */,
+				4F4AD022140996A10068A6D4 /* ierrorcontext.h */,
+				4F4AD023140996A10068A6D4 /* ipersistent.h */,
+				4F4AD024140996A10068A6D4 /* ipluginbase.h */,
+				4F4AD025140996A10068A6D4 /* istringresult.h */,
+				4F4AD026140996A10068A6D4 /* iupdatehandler.h */,
+				4F4AD027140996A10068A6D4 /* keycodes.h */,
+				4F4AD028140996A10068A6D4 /* ustring.cpp */,
+				4F4AD029140996A10068A6D4 /* ustring.h */,
+			);
+			path = base;
+			sourceTree = "<group>";
+		};
+		4F4AD02A140996A10068A6D4 /* gui */ = {
+			isa = PBXGroup;
+			children = (
+				4F4AD02B140996A10068A6D4 /* iplugview.h */,
+			);
+			path = gui;
+			sourceTree = "<group>";
+		};
+		4F4AD02C140996A10068A6D4 /* vst */ = {
+			isa = PBXGroup;
+			children = (
+				4F4AD02D140996A10068A6D4 /* ivstattributes.h */,
+				4F4AD02E140996A10068A6D4 /* ivstaudioprocessor.h */,
+				4F4AD02F140996A10068A6D4 /* ivstcomponent.h */,
+				4F4AD030140996A10068A6D4 /* ivstcontextmenu.h */,
+				4F4AD031140996A10068A6D4 /* ivsteditcontroller.h */,
+				4F4AD032140996A10068A6D4 /* ivstevents.h */,
+				4F4AD033140996A10068A6D4 /* ivsthostapplication.h */,
+				4F4AD034140996A10068A6D4 /* ivstmessage.h */,
+				4F4AD035140996A10068A6D4 /* ivstmidicontrollers.h */,
+				4F4AD036140996A10068A6D4 /* ivstnoteexpression.h */,
+				4F4AD037140996A10068A6D4 /* ivstparameterchanges.h */,
+				4F4AD038140996A10068A6D4 /* ivstplugview.h */,
+				4F4AD039140996A10068A6D4 /* ivstprocesscontext.h */,
+				4F4AD03A140996A10068A6D4 /* ivstrepresentation.h */,
+				4F4AD03B140996A10068A6D4 /* ivstunits.h */,
+				4F4AD03C140996A10068A6D4 /* vstpresetkeys.h */,
+				4F4AD03D140996A10068A6D4 /* vstpshpack4.h */,
+				4F4AD03E140996A10068A6D4 /* vsttypes.h */,
+			);
+			path = vst;
+			sourceTree = "<group>";
+		};
+		4F4AD1F21409A56A0068A6D4 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				4F4AD1F61409A56A0068A6D4 /* libbase.a */,
+				4FA708BF158B47F000BFC572 /* libbase32.a */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		4F4CC4241549BEBF00A9EA21 /* AAX */ = {
+			isa = PBXGroup;
+			children = (
+				4F4CC4251549BED600A9EA21 /* IPlugAAX.cpp */,
+				4F4CC4261549BED600A9EA21 /* IPlugAAX.h */,
+				4F017360154D4BFC0034BE1A /* AAX_CIPlugParameters.cpp */,
+				4F017361154D4BFC0034BE1A /* AAX_CIPlugParameters.h */,
+				4F4F73791576739300C124E3 /* AAX_CIPlugTaperDelegate.h */,
+				4F4CC4401549C15500A9EA21 /* IPlugAAX_Describe.cpp */,
+			);
+			name = AAX;
+			sourceTree = "<group>";
+		};
+		4F75900813B7A91A00DA399F /* MACGUI */ = {
+			isa = PBXGroup;
+			children = (
+				4F78D8EE13B63BA50032E0F3 /* IGraphicsMac.h */,
+				4F78D8F513B63BA50032E0F3 /* IGraphicsMac.mm */,
+				4F78D90713B63BA50032E0F3 /* IGraphicsCarbon.h */,
+				4F78D8F713B63BA50032E0F3 /* IGraphicsCarbon.cpp */,
+				4F78D8F813B63BA50032E0F3 /* IGraphicsCocoa.mm */,
+				4F78D8F913B63BA50032E0F3 /* IGraphicsCocoa.h */,
+			);
+			name = MACGUI;
+			sourceTree = "<group>";
+		};
+		4F78D89413B639100032E0F3 /* English.lproj */ = {
+			isa = PBXGroup;
+			children = (
+				4F78D89513B639100032E0F3 /* InfoPlist.strings */,
+				4F78D89713B639100032E0F3 /* MainMenu.xib */,
+			);
+			name = English.lproj;
+			path = resources/English.lproj;
+			sourceTree = "<group>";
+		};
+		4F78D8BE13B63A700032E0F3 /* rtaudiomidi */ = {
+			isa = PBXGroup;
+			children = (
+				4F78D8BF13B63A700032E0F3 /* RtAudio.cpp */,
+				4F78D8C013B63A700032E0F3 /* RtAudio.h */,
+				4F78D8C113B63A700032E0F3 /* RtError.h */,
+				4F78D8C213B63A700032E0F3 /* RtMidi.cpp */,
+				4F78D8C313B63A700032E0F3 /* RtMidi.h */,
+			);
+			name = rtaudiomidi;
+			path = ../../WDL/rtaudiomidi;
+			sourceTree = SOURCE_ROOT;
+		};
+		4F78D8D013B63B390032E0F3 /* IPlug */ = {
+			isa = PBXGroup;
+			children = (
+				4F4CC4241549BEBF00A9EA21 /* AAX */,
+				4F7F5C7213E95FB8002918FD /* RTAS */,
+				4F78D9FA13B63CA10032E0F3 /* APP */,
+				4F78D9F913B63C920032E0F3 /* AU */,
+				4F3E69001409743C00C4D749 /* VST3 */,
+				4F78D9F713B63C710032E0F3 /* VST */,
+				4F75900813B7A91A00DA399F /* MACGUI */,
+				4F78DAEC13B6427D0032E0F3 /* WINGUI */,
+				4F3EE94513B65A350097B791 /* IPlugOSDetect.h */,
+				4F78D90813B63BA50032E0F3 /* IGraphics.h */,
+				4F78D8F613B63BA50032E0F3 /* IGraphics.cpp */,
+				4FDA440513F3E4F2000B4551 /* IBitmapMonoText.cpp */,
+				4FDA440613F3E4F2000B4551 /* IBitmapMonoText.h */,
+				4F78D8E613B63BA40032E0F3 /* IPlug_include_in_plug_hdr.h */,
+				4F78D8E813B63BA40032E0F3 /* IPlug_include_in_plug_src.h */,
+				4F78D8EC13B63BA40032E0F3 /* IPlugBase.h */,
+				4F78D8ED13B63BA40032E0F3 /* IPlugBase.cpp */,
+				4F78D8EF13B63BA50032E0F3 /* IPlugStructs.cpp */,
+				4F78D8FE13B63BA50032E0F3 /* IPlugStructs.h */,
+				4F78D90313B63BA50032E0F3 /* IParam.h */,
+				4F78D90413B63BA50032E0F3 /* IParam.cpp */,
+				4F78D8E913B63BA40032E0F3 /* IControl.h */,
+				4F78D90913B63BA50032E0F3 /* IControl.cpp */,
+				4F78D8EA13B63BA40032E0F3 /* IKeyboardControl.h */,
+				4F78D8F113B63BA50032E0F3 /* Containers.h */,
+				4F78D8F213B63BA50032E0F3 /* Hosts.h */,
+				4F78D8F313B63BA50032E0F3 /* Hosts.cpp */,
+				4F78D8FC13B63BA50032E0F3 /* IPopupMenu.h */,
+				4F78D8FD13B63BA50032E0F3 /* IPopupMenu.cpp */,
+				4F78D90213B63BA50032E0F3 /* IPlug_Prefix.pch */,
+				4F78D90513B63BA50032E0F3 /* IMidiQueue.h */,
+				4F78D8FA13B63BA50032E0F3 /* Log.h */,
+				4F78D8FB13B63BA50032E0F3 /* Log.cpp */,
+			);
+			name = IPlug;
+			sourceTree = "<group>";
+		};
+		4F78D8D113B63B5D0032E0F3 /* VST2_SDK */ = {
+			isa = PBXGroup;
+			children = (
+				4F78D8D213B63B5D0032E0F3 /* aeffect.h */,
+				4F78D8D313B63B5D0032E0F3 /* aeffectx.h */,
+			);
+			name = VST2_SDK;
+			path = ../../VST_SDK;
+			sourceTree = SOURCE_ROOT;
+		};
+		4F78D9F713B63C710032E0F3 /* VST */ = {
+			isa = PBXGroup;
+			children = (
+				4F78D9EC13B63C6A0032E0F3 /* IPlugVST.cpp */,
+				4F78D9ED13B63C6A0032E0F3 /* IPlugVST.h */,
+			);
+			name = VST;
+			sourceTree = "<group>";
+		};
+		4F78D9F913B63C920032E0F3 /* AU */ = {
+			isa = PBXGroup;
+			children = (
+				4FA88B901444E4C4006CB8DA /* dfx-au-utilities.c */,
+				4FA88B911444E4C4006CB8DA /* dfx-au-utilities.h */,
+				4F78D9FB13B63CD90032E0F3 /* IPlugAU.h */,
+				4F78D9FC13B63CD90032E0F3 /* IPlugAU.cpp */,
+				4F78D9FD13B63CD90032E0F3 /* IPlugAU.r */,
+				4F78D9FE13B63CD90032E0F3 /* IPlugAU_ViewFactory.mm */,
+			);
+			name = AU;
+			sourceTree = "<group>";
+		};
+		4F78D9FA13B63CA10032E0F3 /* APP */ = {
+			isa = PBXGroup;
+			children = (
+				4F78D9EA13B63BE90032E0F3 /* IPlugStandalone.h */,
+				4F78D8EB13B63BA40032E0F3 /* IPlugStandalone.cpp */,
+			);
+			name = APP;
+			sourceTree = "<group>";
+		};
+		4F78DAE913B6423C0032E0F3 /* 3rd Party */ = {
+			isa = PBXGroup;
+			children = (
+				4F24EE751567A6A6006B889A /* AAX_SDK */,
+				4F24EE731567A674006B889A /* RTAS_SDK */,
+				4F3E696A1409778C00C4D749 /* VST3_SDK */,
+				4F78D8D113B63B5D0032E0F3 /* VST2_SDK */,
+				4F78D8BE13B63A700032E0F3 /* rtaudiomidi */,
+			);
+			name = "3rd Party";
+			sourceTree = "<group>";
+		};
+		4F78DAEC13B6427D0032E0F3 /* WINGUI */ = {
+			isa = PBXGroup;
+			children = (
+				4F78DAEA13B642790032E0F3 /* IGraphicsWin.cpp */,
+				4F78DAEB13B642790032E0F3 /* IGraphicsWin.h */,
+			);
+			comments = "Not actually included in builds";
+			name = WINGUI;
+			sourceTree = "<group>";
+		};
+		4F78DB2013B644BD0032E0F3 /* App */ = {
+			isa = PBXGroup;
+			children = (
+				089C167FFE841241C02AAC07 /* AppKit.framework */,
+				4F78D7CF13B637790032E0F3 /* CoreMIDI.framework */,
+				52E41CB90D14C2A900A0943B /* CoreAudio.framework */,
+			);
+			name = App;
+			sourceTree = "<group>";
+		};
+		4F78DB2113B644E80032E0F3 /* App & Plugins */ = {
+			isa = PBXGroup;
+			children = (
+				4F8D4BC413E97664004F7633 /* lice.xcodeproj */,
+				4F78D62313B637200032E0F3 /* CoreFoundation.framework */,
+				D2F7E65807B2D6F200F64583 /* CoreData.framework */,
+				089C1672FE841209C02AAC07 /* Foundation.framework */,
+				52E41CC40D14C2B000A0943B /* CoreServices.framework */,
+				52C4DB180D0E51270007A920 /* Carbon.framework */,
+				1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */,
+			);
+			name = "App & Plugins";
+			sourceTree = "<group>";
+		};
+		4F78DB2213B645060032E0F3 /* AU Plugin */ = {
+			isa = PBXGroup;
+			children = (
+				52E41D920D14C2D600A0943B /* AudioToolbox.framework */,
+				52E41D7E0D14C2D100A0943B /* AudioUnit.framework */,
+			);
+			name = "AU Plugin";
+			sourceTree = "<group>";
+		};
+		4F7F5C7213E95FB8002918FD /* RTAS */ = {
+			isa = PBXGroup;
+			children = (
+				4F7F5C6F13E95FB2002918FD /* IPlugRTAS.cpp */,
+				4F7F5C7013E95FB2002918FD /* IPlugRTAS.h */,
+				4F7F5D2413E9681E002918FD /* IPlugRTAS.r */,
+				4F7F5C9F13E9607A002918FD /* EditorInterface.h */,
+				4F7F5CA013E9607A002918FD /* IPlugCustomUI.cpp */,
+				4F7F5CA113E9607A002918FD /* IPlugCustomUI.h */,
+				4F7F5CA213E9607A002918FD /* IPlugDigiView.h */,
+				4F7F5CA313E9607A002918FD /* IPlugGroup.cpp */,
+				4F7F5CA413E9607A002918FD /* IPlugGroup.h */,
+				4F7F5CA513E9607A002918FD /* IPlugProcess.cpp */,
+				4F7F5CA613E9607A002918FD /* IPlugProcess.h */,
+				4F79A34C146304CD00744AED /* IPlugProcessAS.cpp */,
+				4F79A34D146304CD00744AED /* IPlugProcessAS.h */,
+				4F7F5CA713E9607A002918FD /* IPlugProcessRTAS.cpp */,
+				4F7F5CA813E9607A002918FD /* IPlugProcessRTAS.h */,
+				4F7F5CAA13E9607A002918FD /* ProcessInterface.h */,
+			);
+			name = RTAS;
+			sourceTree = "<group>";
+		};
+		4F7F5CEB13E9651F002918FD /* RTAS Plugin */ = {
+			isa = PBXGroup;
+			children = (
+				4F8B6747158B4F53002FC25B /* PluginLibrary.xcodeproj */,
+				4F7F5CF613E96564002918FD /* System.framework */,
+			);
+			name = "RTAS Plugin";
+			sourceTree = "<group>";
+		};
+		4F8B671E158B4EB2002FC25B /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				4F8B6723158B4EB2002FC25B /* libAAXLibrary.a */,
+				4F8B6725158B4EB2002FC25B /* AAXLibrary_UnitTest */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		4F8B6748158B4F53002FC25B /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				4F8B674F158B4F53002FC25B /* libPluginLibrary.a */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		4F8D4BC513E97664004F7633 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				4F8D4BCC13E97664004F7633 /* lice.a */,
+				4F8D4C1713E976A7004F7633 /* lice32.a */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		4FD16A0213B6303B001D0217 /* img */ = {
+			isa = PBXGroup;
+			children = (
+				5EDC2A951A93B343004EFD46 /* switch.png */,
+				5EDC2A921A93B337004EFD46 /* fader.png */,
+				4F7E1EB116792F6000907FCF /* bg.png */,
+				4F23B9E413B647A00097A67E /* knob.png */,
+			);
+			name = img;
+			sourceTree = "<group>";
+		};
+		4FD16C9D13B6327C001D0217 /* OSX App Wrapper */ = {
+			isa = PBXGroup;
+			children = (
+				4FB3624E13B648FE00DB6B76 /* main.mm */,
+				4F78D89413B639100032E0F3 /* English.lproj */,
+				4FD16C9E13B6327C001D0217 /* app_resource.h */,
+				4FD16C9F13B6327C001D0217 /* app_main.h */,
+				4FD16CA013B6327C001D0217 /* app_main.cpp */,
+				4FD16CA113B6327C001D0217 /* app_dialog.cpp */,
+			);
+			name = "OSX App Wrapper";
+			sourceTree = "<group>";
+		};
+		4FD16CF713B6343B001D0217 /* SWELL */ = {
+			isa = PBXGroup;
+			children = (
+				4FD16D3513B63566001D0217 /* Used by App */,
+				4FD16D1C13B634FB001D0217 /* Used by App & Plugins */,
+			);
+			name = SWELL;
+			sourceTree = "<group>";
+		};
+		4FD16D1C13B634FB001D0217 /* Used by App & Plugins */ = {
+			isa = PBXGroup;
+			children = (
+				4FD16D2B13B6353C001D0217 /* swell-internal.h */,
+				4FD16D3013B6355A001D0217 /* swell-types.h */,
+				4FD16D2213B6351C001D0217 /* swell-functions.h */,
+				4FD16D0B13B634BF001D0217 /* swell-gdi.mm */,
+				4FD16D1713B634E5001D0217 /* swell.h */,
+			);
+			name = "Used by App & Plugins";
+			sourceTree = "<group>";
+		};
+		4FD16D3513B63566001D0217 /* Used by App */ = {
+			isa = PBXGroup;
+			children = (
+				4FD16D0213B63489001D0217 /* swell-menugen.h */,
+				4FD16D0313B63494001D0217 /* swell-dlggen.h */,
+				4FD16D4513B635C8001D0217 /* swellappmain.h */,
+				4FD16D4613B635C8001D0217 /* swellappmain.mm */,
+				4FD16CFB13B63468001D0217 /* swell-appstub.mm */,
+				4FD16D0413B634AA001D0217 /* swell-dlg.mm */,
+				4FD16D1513B634D2001D0217 /* swell-ini.cpp */,
+				4FD16D3913B63582001D0217 /* swell-kb.mm */,
+				4FD16D3B13B6358C001D0217 /* swell-miscdlg.mm */,
+				4FD16D3D13B63595001D0217 /* swell-menu.mm */,
+				4FD16D3F13B635A0001D0217 /* swell-misc.mm */,
+				4FD16D4113B635AB001D0217 /* swell-wnd.mm */,
+				4FD16D4313B635B2001D0217 /* swell.cpp */,
+			);
+			name = "Used by App";
+			sourceTree = "<group>";
+		};
+		4FF01613134E0BCD001447BA /* WDL */ = {
+			isa = PBXGroup;
+			children = (
+				4F78DAE913B6423C0032E0F3 /* 3rd Party */,
+				4F78D8D013B63B390032E0F3 /* IPlug */,
+				4FD16CF713B6343B001D0217 /* SWELL */,
+				4F1F1BE9135B1F60003A5BB2 /* wdlendian.h */,
+				4FF01719134E153A001447BA /* heapbuf.h */,
+				4FF016F4134E14E2001447BA /* mutex.h */,
+				4FF016F5134E14E2001447BA /* ptrlist.h */,
+				4FF016F6134E14E2001447BA /* wdlstring.h */,
+				4F78D8BD13B63A4E0032E0F3 /* wdltypes.h */,
+			);
+			name = WDL;
+			sourceTree = "<group>";
+		};
+		5EDC2A751A93B020004EFD46 /* stk */ = {
+			isa = PBXGroup;
+			children = (
+				5EDC2A761A93B020004EFD46 /* include */,
+				5EDC2A7C1A93B020004EFD46 /* src */,
+			);
+			path = stk;
+			sourceTree = "<group>";
+		};
+		5EDC2A761A93B020004EFD46 /* include */ = {
+			isa = PBXGroup;
+			children = (
+				5EDC2A771A93B020004EFD46 /* ADSR.h */,
+				5EDC2A781A93B020004EFD46 /* Envelope.h */,
+				5EDC2A791A93B020004EFD46 /* Generator.h */,
+				5EDC2A7A1A93B020004EFD46 /* SineWave.h */,
+				5EDC2A7B1A93B020004EFD46 /* Stk.h */,
+			);
+			path = include;
+			sourceTree = "<group>";
+		};
+		5EDC2A7C1A93B020004EFD46 /* src */ = {
+			isa = PBXGroup;
+			children = (
+				5EDC2A7D1A93B020004EFD46 /* ADSR.cpp */,
+				5EDC2A7E1A93B020004EFD46 /* Envelope.cpp */,
+				5EDC2A7F1A93B020004EFD46 /* SineWave.cpp */,
+				5EDC2A801A93B020004EFD46 /* Stk.cpp */,
+			);
+			path = src;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		4F3AE17912C0E5E2001FD7A4 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F3AE17B12C0E5E2001FD7A4 /* resource.h in Headers */,
+				4F3AE17C12C0E5E2001FD7A4 /* AccessiblePeakMeter.h in Headers */,
+				4FF016F7134E14E2001447BA /* mutex.h in Headers */,
+				4FF016F8134E14E2001447BA /* ptrlist.h in Headers */,
+				4FF016F9134E14E2001447BA /* wdlstring.h in Headers */,
+				4FD16D1913B634E5001D0217 /* swell.h in Headers */,
+				4FD16D2413B6351C001D0217 /* swell-functions.h in Headers */,
+				4FD16D2D13B6353C001D0217 /* swell-internal.h in Headers */,
+				5EDC2A841A93B020004EFD46 /* SineWave.h in Headers */,
+				4FD16D3213B6355A001D0217 /* swell-types.h in Headers */,
+				4F78D8D913B63B5D0032E0F3 /* aeffect.h in Headers */,
+				4F78D8DA13B63B5D0032E0F3 /* aeffectx.h in Headers */,
+				4FF0171A134E153A001447BA /* heapbuf.h in Headers */,
+				4F1F1BEA135B1F60003A5BB2 /* wdlendian.h in Headers */,
+				4F78D93E13B63BA50032E0F3 /* IPlug_include_in_plug_hdr.h in Headers */,
+				4F78D94013B63BA50032E0F3 /* IPlug_include_in_plug_src.h in Headers */,
+				4F78D94113B63BA50032E0F3 /* IControl.h in Headers */,
+				4F78D94213B63BA50032E0F3 /* IKeyboardControl.h in Headers */,
+				4F78D94413B63BA50032E0F3 /* IPlugBase.h in Headers */,
+				4F78D94613B63BA50032E0F3 /* IGraphicsMac.h in Headers */,
+				4F78D94913B63BA50032E0F3 /* Containers.h in Headers */,
+				4F78D94A13B63BA50032E0F3 /* Hosts.h in Headers */,
+				4F78D95113B63BA50032E0F3 /* IGraphicsCocoa.h in Headers */,
+				4F78D95213B63BA50032E0F3 /* Log.h in Headers */,
+				4F78D95413B63BA50032E0F3 /* IPopupMenu.h in Headers */,
+				4F78D95613B63BA50032E0F3 /* IPlugStructs.h in Headers */,
+				4F78D95A13B63BA50032E0F3 /* IPlug_Prefix.pch in Headers */,
+				4F78D95B13B63BA50032E0F3 /* IParam.h in Headers */,
+				4F78D95D13B63BA50032E0F3 /* IMidiQueue.h in Headers */,
+				4F78D95F13B63BA50032E0F3 /* IGraphicsCarbon.h in Headers */,
+				5EDC2A851A93B020004EFD46 /* Stk.h in Headers */,
+				5EDC2A831A93B020004EFD46 /* Generator.h in Headers */,
+				4F78D96013B63BA50032E0F3 /* IGraphics.h in Headers */,
+				5EDC2A821A93B020004EFD46 /* Envelope.h in Headers */,
+				5EDC2A811A93B020004EFD46 /* ADSR.h in Headers */,
+				4F78DA0713B63CD90032E0F3 /* IPlugAU.h in Headers */,
+				4F3EE94913B65A350097B791 /* IPlugOSDetect.h in Headers */,
+				4FDA440913F3E4F2000B4551 /* IBitmapMonoText.h in Headers */,
+				4FA88B931444E4C4006CB8DA /* dfx-au-utilities.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4F78DAAC13B640450032E0F3 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F78DABB13B640620032E0F3 /* IPlugStandalone.h in Headers */,
+				4F78DAB813B640530032E0F3 /* RtAudio.h in Headers */,
+				4F78DAB913B640530032E0F3 /* RtError.h in Headers */,
+				4F78DABA13B640530032E0F3 /* RtMidi.h in Headers */,
+				4F78DAB113B640470032E0F3 /* swell-menugen.h in Headers */,
+				4F78DAB213B640470032E0F3 /* swell-dlggen.h in Headers */,
+				4F78DAB313B640470032E0F3 /* swellappmain.h in Headers */,
+				4F78DA7713B640050032E0F3 /* resource.h in Headers */,
+				4F78DA7813B640050032E0F3 /* AccessiblePeakMeter.h in Headers */,
+				4F78DA8A13B640050032E0F3 /* mutex.h in Headers */,
+				4F78DA8B13B640050032E0F3 /* ptrlist.h in Headers */,
+				4F78DA8C13B640050032E0F3 /* wdlstring.h in Headers */,
+				4F78DA8D13B640050032E0F3 /* heapbuf.h in Headers */,
+				4F78DA8E13B640050032E0F3 /* wdlendian.h in Headers */,
+				4F78DA8F13B640050032E0F3 /* swell.h in Headers */,
+				4F78DA9013B640050032E0F3 /* swell-functions.h in Headers */,
+				4F78DA9113B640050032E0F3 /* swell-internal.h in Headers */,
+				4F78DA9213B640050032E0F3 /* swell-types.h in Headers */,
+				4F78DA9313B640050032E0F3 /* aeffect.h in Headers */,
+				4F78DA9413B640050032E0F3 /* aeffectx.h in Headers */,
+				4F78DA9513B640050032E0F3 /* IPlug_include_in_plug_hdr.h in Headers */,
+				4F78DA9613B640050032E0F3 /* IPlug_include_in_plug_src.h in Headers */,
+				4F78DA9713B640050032E0F3 /* IControl.h in Headers */,
+				4F78DA9813B640050032E0F3 /* IKeyboardControl.h in Headers */,
+				4F78DA9913B640050032E0F3 /* IPlugBase.h in Headers */,
+				4F78DA9A13B640050032E0F3 /* IGraphicsMac.h in Headers */,
+				4F78DA9C13B640050032E0F3 /* Containers.h in Headers */,
+				4F78DA9D13B640050032E0F3 /* Hosts.h in Headers */,
+				4F78DA9E13B640050032E0F3 /* IGraphicsCocoa.h in Headers */,
+				4F78DA9F13B640050032E0F3 /* Log.h in Headers */,
+				4F78DAA013B640050032E0F3 /* IPopupMenu.h in Headers */,
+				4F78DAA113B640050032E0F3 /* IPlugStructs.h in Headers */,
+				4F78DAA213B640050032E0F3 /* IPlug_Prefix.pch in Headers */,
+				4F78DAA313B640050032E0F3 /* IParam.h in Headers */,
+				4F78DAA413B640050032E0F3 /* IMidiQueue.h in Headers */,
+				4F78DAA513B640050032E0F3 /* IGraphicsCarbon.h in Headers */,
+				4F78DAA613B640050032E0F3 /* IGraphics.h in Headers */,
+				4F3EE94613B65A350097B791 /* IPlugOSDetect.h in Headers */,
+				4FDA440F13F3E4F2000B4551 /* IBitmapMonoText.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		4F20EEC8132C69FE0030E34C /* VST2 */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 4F20EF2F132C69FE0030E34C /* Build configuration list for PBXNativeTarget "VST2" */;
+			buildPhases = (
+				4F20EEC9132C69FE0030E34C /* Resources */,
+				4F20EECA132C69FE0030E34C /* Sources */,
+				4F20EF2C132C69FE0030E34C /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				4F8D4C2D13E977CD004F7633 /* PBXTargetDependency */,
+			);
+			name = VST2;
+			productInstallPath = "$(HOME)/Library/Bundles";
+			productName = IPlugExample;
+			productReference = 4F20EF33132C69FE0030E34C /* AccessiblePeakMeter.vst */;
+			productType = "com.apple.product-type.bundle";
+		};
+		4F3AE17812C0E5E2001FD7A4 /* AU */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 4F3AE1DC12C0E5E2001FD7A4 /* Build configuration list for PBXNativeTarget "AU" */;
+			buildPhases = (
+				4F3AE17912C0E5E2001FD7A4 /* Headers */,
+				4F3AE1A212C0E5E2001FD7A4 /* Sources */,
+				4F25BECE12C61F47005D51F7 /* Resources */,
+				4F3AE1D312C0E5E2001FD7A4 /* Frameworks */,
+				4F3AE1DA12C0E5E2001FD7A4 /* Rez */,
+				4F744D4C14005ADA002FAD90 /* ShellScript */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				4F8D4C3A13E97859004F7633 /* PBXTargetDependency */,
+			);
+			name = AU;
+			productName = IPlugExampleAU;
+			productReference = 4F78DB5F13B6462B0032E0F3 /* AccessiblePeakMeter.component */;
+			productType = "com.apple.product-type.bundle";
+		};
+		4F7F5C4213E95EC8002918FD /* RTAS */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 4F7F5C6413E95EC8002918FD /* Build configuration list for PBXNativeTarget "RTAS" */;
+			buildPhases = (
+				4F7F5C4813E95EC8002918FD /* Sources */,
+				4F7F5C5F13E95EC8002918FD /* Frameworks */,
+				4F7F5D3113E9688A002918FD /* Rez */,
+				4F7F5C4313E95EC8002918FD /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				4F8D4C3813E9783A004F7633 /* PBXTargetDependency */,
+				4F8B6765158B4F67002FC25B /* PBXTargetDependency */,
+			);
+			name = RTAS;
+			productInstallPath = "$(HOME)/Library/Bundles";
+			productName = IPlugExample;
+			productReference = 4F7F5C6813E95EC8002918FD /* AccessiblePeakMeter.dpm */;
+			productType = "com.apple.product-type.bundle";
+		};
+		4F9828AA140A9EB700F3FCC1 /* VST3 */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 4F9828DC140A9EB700F3FCC1 /* Build configuration list for PBXNativeTarget "VST3" */;
+			buildPhases = (
+				4F9828AF140A9EB700F3FCC1 /* Resources */,
+				4F9828B5140A9EB700F3FCC1 /* Sources */,
+				4F9828D7140A9EB700F3FCC1 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				4F9828AD140A9EB700F3FCC1 /* PBXTargetDependency */,
+				4F9828F3140A9ED500F3FCC1 /* PBXTargetDependency */,
+			);
+			name = VST3;
+			productInstallPath = "$(HOME)/Library/Bundles";
+			productName = IPlugExample;
+			productReference = 4F9828E0140A9EB700F3FCC1 /* AccessiblePeakMeter.vst3 */;
+			productType = "com.apple.product-type.bundle";
+		};
+		4FB600121567CB0A0020189A /* AAX */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 4FB6002F1567CB0A0020189A /* Build configuration list for PBXNativeTarget "AAX" */;
+			buildPhases = (
+				4FB600151567CB0A0020189A /* Resources */,
+				4FB600171567CB0A0020189A /* Sources */,
+				4FB6002A1567CB0A0020189A /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				4FB600501567CB990020189A /* PBXTargetDependency */,
+				4F3B0B43158B509A001B0CEF /* PBXTargetDependency */,
+			);
+			name = AAX;
+			productInstallPath = "$(HOME)/Library/Bundles";
+			productName = IPlugExample;
+			productReference = 4FB600331567CB0A0020189A /* AccessiblePeakMeter.aaxplugin */;
+			productType = "com.apple.product-type.bundle";
+		};
+		4FD16A0813B63081001D0217 /* APP */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 4FD16A0F13B63082001D0217 /* Build configuration list for PBXNativeTarget "APP" */;
+			buildPhases = (
+				4F78DAAC13B640450032E0F3 /* Headers */,
+				4FD16A0513B63081001D0217 /* Resources */,
+				4FD16A0613B63081001D0217 /* Sources */,
+				4FD16A0713B63081001D0217 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				4F678B6D13E984B200A6A9BB /* PBXTargetDependency */,
+			);
+			name = APP;
+			productName = "OSXAPP_32&64_intel";
+			productReference = 4FD16A0913B63081001D0217 /* AccessiblePeakMeter.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		089C1669FE841209C02AAC07 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				BuildIndependentTargetsInParallel = YES;
+			};
+			buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "AccessiblePeakMeter" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 1;
+			knownRegions = (
+				English,
+				Japanese,
+				French,
+				German,
+			);
+			mainGroup = 089C166AFE841209C02AAC07 /* IPlugExample */;
+			projectDirPath = "";
+			projectReferences = (
+				{
+					ProductGroup = 4F8B671E158B4EB2002FC25B /* Products */;
+					ProjectRef = 4FF7B0F3156A831000E6CB12 /* AAXLibrary.xcodeproj */;
+				},
+				{
+					ProductGroup = 4F4AD1F21409A56A0068A6D4 /* Products */;
+					ProjectRef = 4F4AD1F11409A56A0068A6D4 /* base.xcodeproj */;
+				},
+				{
+					ProductGroup = 4F8D4BC513E97664004F7633 /* Products */;
+					ProjectRef = 4F8D4BC413E97664004F7633 /* lice.xcodeproj */;
+				},
+				{
+					ProductGroup = 4F8B6748158B4F53002FC25B /* Products */;
+					ProjectRef = 4F8B6747158B4F53002FC25B /* PluginLibrary.xcodeproj */;
+				},
+			);
+			projectRoot = "";
+			targets = (
+				4F78DAF113B643600032E0F3 /* All */,
+				4FD16A0813B63081001D0217 /* APP */,
+				4F20EEC8132C69FE0030E34C /* VST2 */,
+				4F9828AA140A9EB700F3FCC1 /* VST3 */,
+				4F3AE17812C0E5E2001FD7A4 /* AU */,
+				4F7F5C4213E95EC8002918FD /* RTAS */,
+				4FB600121567CB0A0020189A /* AAX */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXReferenceProxy section */
+		4F4AD1F61409A56A0068A6D4 /* libbase.a */ = {
+			isa = PBXReferenceProxy;
+			fileType = archive.ar;
+			path = libbase.a;
+			remoteRef = 4F4AD1F51409A56A0068A6D4 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		4F8B6723158B4EB2002FC25B /* libAAXLibrary.a */ = {
+			isa = PBXReferenceProxy;
+			fileType = archive.ar;
+			path = libAAXLibrary.a;
+			remoteRef = 4F8B6722158B4EB2002FC25B /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		4F8B6725158B4EB2002FC25B /* AAXLibrary_UnitTest */ = {
+			isa = PBXReferenceProxy;
+			fileType = "compiled.mach-o.executable";
+			path = AAXLibrary_UnitTest;
+			remoteRef = 4F8B6724158B4EB2002FC25B /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		4F8B674F158B4F53002FC25B /* libPluginLibrary.a */ = {
+			isa = PBXReferenceProxy;
+			fileType = archive.ar;
+			path = libPluginLibrary.a;
+			remoteRef = 4F8B674E158B4F53002FC25B /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		4F8D4BCC13E97664004F7633 /* lice.a */ = {
+			isa = PBXReferenceProxy;
+			fileType = archive.ar;
+			path = lice.a;
+			remoteRef = 4F8D4BCB13E97664004F7633 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		4F8D4C1713E976A7004F7633 /* lice32.a */ = {
+			isa = PBXReferenceProxy;
+			fileType = archive.ar;
+			path = lice32.a;
+			remoteRef = 4F8D4C1613E976A7004F7633 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		4FA708BF158B47F000BFC572 /* libbase32.a */ = {
+			isa = PBXReferenceProxy;
+			fileType = archive.ar;
+			path = libbase32.a;
+			remoteRef = 4FA708BE158B47F000BFC572 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+/* End PBXReferenceProxy section */
+
+/* Begin PBXResourcesBuildPhase section */
+		4F20EEC9132C69FE0030E34C /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				5EDC2A971A93BA2E004EFD46 /* switch.png in Resources */,
+				4F23B9F313B647A00097A67E /* knob.png in Resources */,
+				5EDC2A9D1A93BA33004EFD46 /* fader.png in Resources */,
+				4F7E1EC516792F6000907FCF /* bg.png in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4F25BECE12C61F47005D51F7 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				5EDC2A991A93BA2F004EFD46 /* switch.png in Resources */,
+				4F23BA0C13B647A00097A67E /* knob.png in Resources */,
+				5EDC2A9F1A93BA34004EFD46 /* fader.png in Resources */,
+				4F7E1EBD16792F6000907FCF /* bg.png in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4F7F5C4313E95EC8002918FD /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				5EDC2A9A1A93BA30004EFD46 /* switch.png in Resources */,
+				4F7F5C4613E95EC8002918FD /* knob.png in Resources */,
+				5EDC2AA01A93BA34004EFD46 /* fader.png in Resources */,
+				4F7E1EB516792F6000907FCF /* bg.png in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4F9828AF140A9EB700F3FCC1 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				5EDC2A981A93BA2F004EFD46 /* switch.png in Resources */,
+				4F9828B1140A9EB700F3FCC1 /* knob.png in Resources */,
+				5EDC2A9E1A93BA34004EFD46 /* fader.png in Resources */,
+				4F7E1EC116792F6000907FCF /* bg.png in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4FB600151567CB0A0020189A /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				5EDC2A9B1A93BA30004EFD46 /* switch.png in Resources */,
+				4FB600161567CB0A0020189A /* knob.png in Resources */,
+				5EDC2AA11A93BA35004EFD46 /* fader.png in Resources */,
+				4F7E1EB916792F6000907FCF /* bg.png in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4FD16A0513B63081001D0217 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F78D88613B6382B0032E0F3 /* AccessiblePeakMeter.icns in Resources */,
+				4F78D89913B639100032E0F3 /* InfoPlist.strings in Resources */,
+				4F78D89A13B639100032E0F3 /* MainMenu.xib in Resources */,
+				5EDC2A961A93BA2E004EFD46 /* switch.png in Resources */,
+				5EDC2A9C1A93BA33004EFD46 /* fader.png in Resources */,
+				4F23B9FD13B647A00097A67E /* knob.png in Resources */,
+				4F7E1EC916792F6000907FCF /* bg.png in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXRezBuildPhase section */
+		4F3AE1DA12C0E5E2001FD7A4 /* Rez */ = {
+			isa = PBXRezBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F78DA0913B63CD90032E0F3 /* IPlugAU.r in Rez */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4F7F5D3113E9688A002918FD /* Rez */ = {
+			isa = PBXRezBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F7F5D2C13E9686E002918FD /* IPlugRTAS.r in Rez */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXRezBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		4F744D4C14005ADA002FAD90 /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			comments = "reset audiounit caches";
+			files = (
+			);
+			inputPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "if [ -f \"$HOME/Library/Application Support/AU Lab/com.apple.audio.aulab_componentcache.plist\" ]\n  then\n\trm \"$HOME/Library/Application Support/AU Lab/com.apple.audio.aulab_componentcache.plist\"\nfi\n\nif [ -f \"$HOME/Library/Caches/com.apple.audiounits.cache\" ]\n  then\n\trm \"$HOME/Library/Caches/com.apple.audiounits.cache\"\nfi";
+			showEnvVarsInLog = 0;
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		4F20EECA132C69FE0030E34C /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F20EECB132C69FE0030E34C /* AccessiblePeakMeter.cpp in Sources */,
+				4FD16D1213B634BF001D0217 /* swell-gdi.mm in Sources */,
+				4F78D9BB13B63BA50032E0F3 /* IPlugBase.cpp in Sources */,
+				5EDC2A881A93B020004EFD46 /* Envelope.cpp in Sources */,
+				5EDC2A861A93B020004EFD46 /* ADSR.cpp in Sources */,
+				5EDC2A8A1A93B020004EFD46 /* SineWave.cpp in Sources */,
+				4F78D9BC13B63BA50032E0F3 /* IPlugStructs.cpp in Sources */,
+				4F78D9BD13B63BA50032E0F3 /* Hosts.cpp in Sources */,
+				4F78D9BF13B63BA50032E0F3 /* IGraphicsMac.mm in Sources */,
+				4F78D9C013B63BA50032E0F3 /* IGraphics.cpp in Sources */,
+				4F78D9C113B63BA50032E0F3 /* IGraphicsCarbon.cpp in Sources */,
+				5EDC2A8C1A93B020004EFD46 /* Stk.cpp in Sources */,
+				4F78D9C213B63BA50032E0F3 /* IGraphicsCocoa.mm in Sources */,
+				4F78D9C313B63BA50032E0F3 /* Log.cpp in Sources */,
+				4F78D9C413B63BA50032E0F3 /* IPopupMenu.cpp in Sources */,
+				4F78D9C813B63BA50032E0F3 /* IParam.cpp in Sources */,
+				4F78D9C913B63BA50032E0F3 /* IControl.cpp in Sources */,
+				4F78D9F313B63C6A0032E0F3 /* IPlugVST.cpp in Sources */,
+				4FDA440C13F3E4F2000B4551 /* IBitmapMonoText.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4F3AE1A212C0E5E2001FD7A4 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F3AE1A312C0E5E2001FD7A4 /* AccessiblePeakMeter.cpp in Sources */,
+				4FD16D0E13B634BF001D0217 /* swell-gdi.mm in Sources */,
+				4F78D94513B63BA50032E0F3 /* IPlugBase.cpp in Sources */,
+				5EDC2A8D1A93B020004EFD46 /* Stk.cpp in Sources */,
+				5EDC2A8B1A93B020004EFD46 /* SineWave.cpp in Sources */,
+				4F78D94713B63BA50032E0F3 /* IPlugStructs.cpp in Sources */,
+				4F78D94B13B63BA50032E0F3 /* Hosts.cpp in Sources */,
+				4F78D94D13B63BA50032E0F3 /* IGraphicsMac.mm in Sources */,
+				4F78D94E13B63BA50032E0F3 /* IGraphics.cpp in Sources */,
+				5EDC2A891A93B020004EFD46 /* Envelope.cpp in Sources */,
+				4F78D94F13B63BA50032E0F3 /* IGraphicsCarbon.cpp in Sources */,
+				4F78D95013B63BA50032E0F3 /* IGraphicsCocoa.mm in Sources */,
+				5EDC2A871A93B020004EFD46 /* ADSR.cpp in Sources */,
+				4F78D95313B63BA50032E0F3 /* Log.cpp in Sources */,
+				4F78D95513B63BA50032E0F3 /* IPopupMenu.cpp in Sources */,
+				4F78D95C13B63BA50032E0F3 /* IParam.cpp in Sources */,
+				4F78D96113B63BA50032E0F3 /* IControl.cpp in Sources */,
+				4F78DA0813B63CD90032E0F3 /* IPlugAU.cpp in Sources */,
+				4F78DA0A13B63CD90032E0F3 /* IPlugAU_ViewFactory.mm in Sources */,
+				4FDA440813F3E4F2000B4551 /* IBitmapMonoText.cpp in Sources */,
+				4F296BDA1678E6C800C0F5C2 /* dfx-au-utilities.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4F7F5C4813E95EC8002918FD /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F7F5C4913E95EC8002918FD /* AccessiblePeakMeter.cpp in Sources */,
+				4F7F5C5013E95EC8002918FD /* swell-gdi.mm in Sources */,
+				4F7F5C5113E95EC8002918FD /* IPlugBase.cpp in Sources */,
+				4F7F5C5213E95EC8002918FD /* IPlugStructs.cpp in Sources */,
+				4F7F5C5313E95EC8002918FD /* Hosts.cpp in Sources */,
+				4F7F5C5413E95EC8002918FD /* IGraphicsMac.mm in Sources */,
+				4F7F5C5513E95EC8002918FD /* IGraphics.cpp in Sources */,
+				4F7F5C5613E95EC8002918FD /* IGraphicsCarbon.cpp in Sources */,
+				4F7F5C5713E95EC8002918FD /* IGraphicsCocoa.mm in Sources */,
+				4F7F5C5813E95EC8002918FD /* Log.cpp in Sources */,
+				4F7F5C5913E95EC8002918FD /* IPopupMenu.cpp in Sources */,
+				4F7F5C5A13E95EC8002918FD /* IParam.cpp in Sources */,
+				4F7F5C5B13E95EC8002918FD /* IControl.cpp in Sources */,
+				4F7F5C7113E95FB2002918FD /* IPlugRTAS.cpp in Sources */,
+				4F7F5CAD13E9607A002918FD /* digicode1.cpp in Sources */,
+				4F7F5CAE13E9607A002918FD /* digicode2.cpp in Sources */,
+				4F7F5CAF13E9607A002918FD /* digicode3.cpp in Sources */,
+				4F7F5CB013E9607A002918FD /* IPlugCustomUI.cpp in Sources */,
+				4F7F5CB113E9607A002918FD /* IPlugGroup.cpp in Sources */,
+				4F7F5CB213E9607A002918FD /* IPlugProcess.cpp in Sources */,
+				4F7F5CB313E9607A002918FD /* IPlugProcessRTAS.cpp in Sources */,
+				4FDA440713F3E4F2000B4551 /* IBitmapMonoText.cpp in Sources */,
+				4F79A34E146304CD00744AED /* IPlugProcessAS.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4F9828B5140A9EB700F3FCC1 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4F9828B6140A9EB700F3FCC1 /* AccessiblePeakMeter.cpp in Sources */,
+				4F9828B7140A9EB700F3FCC1 /* swell-gdi.mm in Sources */,
+				4F9828B8140A9EB700F3FCC1 /* IPlugBase.cpp in Sources */,
+				4F9828B9140A9EB700F3FCC1 /* IPlugStructs.cpp in Sources */,
+				4F9828BA140A9EB700F3FCC1 /* Hosts.cpp in Sources */,
+				4F9828BB140A9EB700F3FCC1 /* IGraphicsMac.mm in Sources */,
+				4F9828BC140A9EB700F3FCC1 /* IGraphics.cpp in Sources */,
+				4F9828BD140A9EB700F3FCC1 /* IGraphicsCarbon.cpp in Sources */,
+				4F9828BE140A9EB700F3FCC1 /* IGraphicsCocoa.mm in Sources */,
+				4F9828BF140A9EB700F3FCC1 /* Log.cpp in Sources */,
+				4F9828C0140A9EB700F3FCC1 /* IPopupMenu.cpp in Sources */,
+				4F9828C1140A9EB700F3FCC1 /* IParam.cpp in Sources */,
+				4F9828C2140A9EB700F3FCC1 /* IControl.cpp in Sources */,
+				4F9828C3140A9EB700F3FCC1 /* IBitmapMonoText.cpp in Sources */,
+				4F9828C4140A9EB700F3FCC1 /* IPlugVST3.cpp in Sources */,
+				4F9828C5140A9EB700F3FCC1 /* memorystream.cpp in Sources */,
+				4F9828C6140A9EB700F3FCC1 /* pluginview.cpp in Sources */,
+				4F9828C7140A9EB700F3FCC1 /* macmain.cpp in Sources */,
+				4F9828C8140A9EB700F3FCC1 /* pluginfactoryvst3.cpp in Sources */,
+				4F9828C9140A9EB700F3FCC1 /* vstaudioeffect.cpp in Sources */,
+				4F9828CA140A9EB700F3FCC1 /* vstbus.cpp in Sources */,
+				4F9828CB140A9EB700F3FCC1 /* vstcomponent.cpp in Sources */,
+				4F9828CC140A9EB700F3FCC1 /* vstcomponentbase.cpp in Sources */,
+				4F9828CE140A9EB700F3FCC1 /* vstinitiids.cpp in Sources */,
+				4F9828CF140A9EB700F3FCC1 /* vstnoteexpressiontypes.cpp in Sources */,
+				4F9828D0140A9EB700F3FCC1 /* vstparameters.cpp in Sources */,
+				4F9828D1140A9EB700F3FCC1 /* vstpresetfile.cpp in Sources */,
+				4F9828D2140A9EB700F3FCC1 /* vstrepresentation.cpp in Sources */,
+				4F9828D3140A9EB700F3FCC1 /* vstsinglecomponenteffect.cpp in Sources */,
+				4F9828D4140A9EB700F3FCC1 /* conststringtable.cpp in Sources */,
+				4F9828D5140A9EB700F3FCC1 /* funknown.cpp in Sources */,
+				4F9828D6140A9EB700F3FCC1 /* ustring.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4FB600171567CB0A0020189A /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4FB600181567CB0A0020189A /* AccessiblePeakMeter.cpp in Sources */,
+				4FB600191567CB0A0020189A /* swell-gdi.mm in Sources */,
+				4FB6001A1567CB0A0020189A /* IPlugBase.cpp in Sources */,
+				4FB6001B1567CB0A0020189A /* IPlugStructs.cpp in Sources */,
+				4FB6001C1567CB0A0020189A /* Hosts.cpp in Sources */,
+				4FB6001D1567CB0A0020189A /* IGraphicsMac.mm in Sources */,
+				4FB6001E1567CB0A0020189A /* IGraphics.cpp in Sources */,
+				4FB6001F1567CB0A0020189A /* IGraphicsCarbon.cpp in Sources */,
+				4FB600201567CB0A0020189A /* IGraphicsCocoa.mm in Sources */,
+				4FB600211567CB0A0020189A /* Log.cpp in Sources */,
+				4FB600221567CB0A0020189A /* IPopupMenu.cpp in Sources */,
+				4FB600231567CB0A0020189A /* IParam.cpp in Sources */,
+				4FB600241567CB0A0020189A /* IControl.cpp in Sources */,
+				4FB600251567CB0A0020189A /* IBitmapMonoText.cpp in Sources */,
+				4FB600261567CB0A0020189A /* AAX_Exports.cpp in Sources */,
+				4FB600271567CB0A0020189A /* IPlugAAX.cpp in Sources */,
+				4FB600281567CB0A0020189A /* IPlugAAX_Describe.cpp in Sources */,
+				4FB600291567CB0A0020189A /* AAX_CIPlugParameters.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4FD16A0613B63081001D0217 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4FD16CFC13B63468001D0217 /* swell-appstub.mm in Sources */,
+				4FD16D0513B634AA001D0217 /* swell-dlg.mm in Sources */,
+				4FD16D0C13B634BF001D0217 /* swell-gdi.mm in Sources */,
+				4FD16D1613B634D2001D0217 /* swell-ini.cpp in Sources */,
+				4FD16D3A13B63582001D0217 /* swell-kb.mm in Sources */,
+				4FD16D3C13B6358C001D0217 /* swell-miscdlg.mm in Sources */,
+				4FD16D3E13B63595001D0217 /* swell-menu.mm in Sources */,
+				4FD16D4013B635A0001D0217 /* swell-misc.mm in Sources */,
+				4FD16D4213B635AB001D0217 /* swell-wnd.mm in Sources */,
+				4FD16D4413B635B2001D0217 /* swell.cpp in Sources */,
+				4FD16D4713B635C8001D0217 /* swellappmain.mm in Sources */,
+				4F78D8C413B63A700032E0F3 /* RtAudio.cpp in Sources */,
+				4F78D8C513B63A700032E0F3 /* RtMidi.cpp in Sources */,
+				4F78D90A13B63BA50032E0F3 /* IPlugStandalone.cpp in Sources */,
+				4F78D90B13B63BA50032E0F3 /* IPlugBase.cpp in Sources */,
+				4F78D90C13B63BA50032E0F3 /* IPlugStructs.cpp in Sources */,
+				4F78D90D13B63BA50032E0F3 /* Hosts.cpp in Sources */,
+				4F78D90F13B63BA50032E0F3 /* IGraphicsMac.mm in Sources */,
+				4F78D91013B63BA50032E0F3 /* IGraphics.cpp in Sources */,
+				4F78D91113B63BA50032E0F3 /* IGraphicsCarbon.cpp in Sources */,
+				4F78D91213B63BA50032E0F3 /* IGraphicsCocoa.mm in Sources */,
+				4F78D91313B63BA50032E0F3 /* Log.cpp in Sources */,
+				4F78D91413B63BA50032E0F3 /* IPopupMenu.cpp in Sources */,
+				4F78D91813B63BA50032E0F3 /* IParam.cpp in Sources */,
+				4F78D91913B63BA50032E0F3 /* IControl.cpp in Sources */,
+				4F78DA5A13B63F150032E0F3 /* AccessiblePeakMeter.cpp in Sources */,
+				4FD16CA213B6327D001D0217 /* app_main.cpp in Sources */,
+				4FD16CA313B6327D001D0217 /* app_dialog.cpp in Sources */,
+				4FB3624F13B648FE00DB6B76 /* main.mm in Sources */,
+				4FDA440E13F3E4F2000B4551 /* IBitmapMonoText.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		4F3B0B43158B509A001B0CEF /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = AAXLibrary;
+			targetProxy = 4F3B0B42158B509A001B0CEF /* PBXContainerItemProxy */;
+		};
+		4F678B6D13E984B200A6A9BB /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = "lice_32&64_intel";
+			targetProxy = 4F678B6C13E984B200A6A9BB /* PBXContainerItemProxy */;
+		};
+		4F789ED016763E47009EF688 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 4FB600121567CB0A0020189A /* AAX */;
+			targetProxy = 4F789ECF16763E47009EF688 /* PBXContainerItemProxy */;
+		};
+		4F78DAF613B6436B0032E0F3 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 4FD16A0813B63081001D0217 /* APP */;
+			targetProxy = 4F78DAF513B6436B0032E0F3 /* PBXContainerItemProxy */;
+		};
+		4F78DAF813B6436B0032E0F3 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 4F20EEC8132C69FE0030E34C /* VST2 */;
+			targetProxy = 4F78DAF713B6436B0032E0F3 /* PBXContainerItemProxy */;
+		};
+		4F78DAFA13B6436B0032E0F3 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 4F3AE17812C0E5E2001FD7A4 /* AU */;
+			targetProxy = 4F78DAF913B6436B0032E0F3 /* PBXContainerItemProxy */;
+		};
+		4F8B6765158B4F67002FC25B /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = "Plugin Library";
+			targetProxy = 4F8B6764158B4F67002FC25B /* PBXContainerItemProxy */;
+		};
+		4F8D4C2D13E977CD004F7633 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = "lice_32&64_intel";
+			targetProxy = 4F8D4C2C13E977CD004F7633 /* PBXContainerItemProxy */;
+		};
+		4F8D4C3813E9783A004F7633 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = lice_32_intel;
+			targetProxy = 4F8D4C3713E9783A004F7633 /* PBXContainerItemProxy */;
+		};
+		4F8D4C3A13E97859004F7633 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = "lice_32&64_intel";
+			targetProxy = 4F8D4C3913E97859004F7633 /* PBXContainerItemProxy */;
+		};
+		4F8D4C6313E97B3D004F7633 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 4F7F5C4213E95EC8002918FD /* RTAS */;
+			targetProxy = 4F8D4C6213E97B3D004F7633 /* PBXContainerItemProxy */;
+		};
+		4F9828AD140A9EB700F3FCC1 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = base;
+			targetProxy = 4F9828AE140A9EB700F3FCC1 /* PBXContainerItemProxy */;
+		};
+		4F9828F3140A9ED500F3FCC1 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = "lice_32&64_intel";
+			targetProxy = 4F9828F2140A9ED500F3FCC1 /* PBXContainerItemProxy */;
+		};
+		4F9828F8140A9F0200F3FCC1 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 4F9828AA140A9EB700F3FCC1 /* VST3 */;
+			targetProxy = 4F9828F7140A9F0200F3FCC1 /* PBXContainerItemProxy */;
+		};
+		4FB600501567CB990020189A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = "lice_32&64_intel";
+			targetProxy = 4FB6004F1567CB990020189A /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+		4F78D89513B639100032E0F3 /* InfoPlist.strings */ = {
+			isa = PBXVariantGroup;
+			children = (
+				4F78D89613B639100032E0F3 /* English */,
+			);
+			name = InfoPlist.strings;
+			sourceTree = "<group>";
+		};
+		4F78D89713B639100032E0F3 /* MainMenu.xib */ = {
+			isa = PBXVariantGroup;
+			children = (
+				4F78D89813B639100032E0F3 /* English */,
+			);
+			name = MainMenu.xib;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		1DEB913F08733D840010E9CD /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 4FCF15AF133124D1009A6277 /* AccessiblePeakMeter.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+				COPY_PHASE_STRIP = NO;
+				DEPLOYMENT_LOCATION = YES;
+				EXECUTABLE_EXTENSION = "";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_OPTIMIZATION_LEVEL = "$(DEBUG_OPTIMIZE)";
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = $IPLUG_PATH/IPlug_Prefix.pch;
+				GCC_PREPROCESSOR_DEFINITIONS = "$(DEBUG_DEFS)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = "$(COCOA_DEFS)";
+				GCC_VERSION = "$(COMPILER)";
+				GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				GENERATE_PKGINFO_FILE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(IPLUG_PATH)",
+					"$(ADDITIONAL_INCLUDES)",
+				);
+				INFOPLIST_EXPAND_BUILD_SETTINGS = YES;
+				INFOPLIST_PREPROCESS = NO;
+				INSTALL_GROUP = admin;
+				INSTALL_OWNER = root;
+				INSTALL_PATH = /;
+				LIBRARY_SEARCH_PATHS = "$(ADDITIONAL_LIBRARY_PATHS)";
+				ONLY_ACTIVE_ARCH = YES;
+				OTHER_CPLUSPLUSFLAGS = (
+					"$(OTHER_CFLAGS)",
+					"$(GCC_CFLAGS)",
+				);
+				PREBINDING = NO;
+				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
+				PRODUCT_NAME = "$(BINARY_NAME)";
+				SDKROOT = "$(BASE_SDK)";
+				SKIP_INSTALL = NO;
+				STRIP_INSTALLED_PRODUCT = NO;
+				SYMROOT = "build-mac";
+				VALID_ARCHS = "i386 x86_64";
+				WRAPPER_EXTENSION = "";
+			};
+			name = Debug;
+		};
+		1DEB914008733D840010E9CD /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 4FCF15AF133124D1009A6277 /* AccessiblePeakMeter.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				DEPLOYMENT_LOCATION = YES;
+				EXECUTABLE_EXTENSION = "";
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_OPTIMIZATION_LEVEL = "$(RELEASE_OPTIMIZE)";
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = $IPLUG_PATH/IPlug_Prefix.pch;
+				GCC_PREPROCESSOR_DEFINITIONS = "$(RELEASE_DEFS)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = "$(COCOA_DEFS)";
+				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+				GCC_VERSION = "$(COMPILER)";
+				GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				GENERATE_PKGINFO_FILE = YES;
+				GENERATE_PROFILING_CODE = "$(PROFILE)";
+				HEADER_SEARCH_PATHS = (
+					"$(IPLUG_PATH)",
+					"$(ADDITIONAL_INCLUDES)",
+				);
+				INFOPLIST_EXPAND_BUILD_SETTINGS = YES;
+				INFOPLIST_PREPROCESS = NO;
+				INSTALL_GROUP = admin;
+				INSTALL_OWNER = root;
+				INSTALL_PATH = /;
+				LIBRARY_SEARCH_PATHS = "$(ADDITIONAL_LIBRARY_PATHS)";
+				OTHER_CPLUSPLUSFLAGS = (
+					"$(OTHER_CFLAGS)",
+					"$(GCC_CFLAGS)",
+				);
+				PREBINDING = NO;
+				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
+				PRODUCT_NAME = "$(BINARY_NAME)";
+				SDKROOT = "$(BASE_SDK)";
+				SKIP_INSTALL = NO;
+				SYMROOT = "build-mac";
+				VALID_ARCHS = "i386 x86_64";
+				WRAPPER_EXTENSION = "";
+			};
+			name = Release;
+		};
+		4F20EF30132C69FE0030E34C /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DSTROOT = "$(VST_FOLDER)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(VST_DEFS)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-VST2-Info.plist";
+				SKIP_INSTALL = NO;
+				WRAPPER_EXTENSION = vst;
+			};
+			name = Debug;
+		};
+		4F20EF31132C69FE0030E34C /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DSTROOT = "$(VST_FOLDER)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(VST_DEFS)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-VST2-Info.plist";
+				SKIP_INSTALL = NO;
+				WRAPPER_EXTENSION = vst;
+			};
+			name = Release;
+		};
+		4F20EF32132C69FE0030E34C /* Tracer */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DSTROOT = "$(VST_FOLDER)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(VST_DEFS)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-VST2-Info.plist";
+				SKIP_INSTALL = NO;
+				WRAPPER_EXTENSION = vst;
+			};
+			name = Tracer;
+		};
+		4F3AE1DD12C0E5E2001FD7A4 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DSTROOT = "$(AU_FOLDER)";
+				EXPORTED_SYMBOLS_FILE = AccessiblePeakMeter.exp;
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(AU_DEFS)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-AU-Info.plist";
+				OTHER_LDFLAGS = "-bundle";
+				OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I $CA_SDK/AudioUnits/AUPublic/AUBase";
+				PREBINDING = YES;
+				REZ_SEARCH_PATHS = (
+					/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers,
+					$CA_SDK/AudioUnits/AUPublic/AUBase,
+				);
+				SKIP_INSTALL = NO;
+				WRAPPER_EXTENSION = component;
+			};
+			name = Debug;
+		};
+		4F3AE1DE12C0E5E2001FD7A4 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DSTROOT = "$(AU_FOLDER)";
+				EXPORTED_SYMBOLS_FILE = AccessiblePeakMeter.exp;
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(AU_DEFS)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-AU-Info.plist";
+				OTHER_LDFLAGS = "-bundle";
+				OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I $CA_SDK/AudioUnits/AUPublic/AUBase";
+				PREBINDING = YES;
+				REZ_SEARCH_PATHS = (
+					/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers,
+					$CA_SDK/AudioUnits/AUPublic/AUBase,
+				);
+				SKIP_INSTALL = NO;
+				WRAPPER_EXTENSION = component;
+			};
+			name = Release;
+		};
+		4F3AE1DF12C0E5E2001FD7A4 /* Tracer */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DSTROOT = "$(AU_FOLDER)";
+				EXPORTED_SYMBOLS_FILE = AccessiblePeakMeter.exp;
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(AU_DEFS)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-AU-Info.plist";
+				OTHER_LDFLAGS = "-bundle";
+				OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers -I $CA_SDK/AudioUnits/AUPublic/AUBase";
+				PREBINDING = YES;
+				REZ_SEARCH_PATHS = (
+					/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers,
+					$CA_SDK/AudioUnits/AUPublic/AUBase,
+				);
+				SKIP_INSTALL = NO;
+				WRAPPER_EXTENSION = component;
+			};
+			name = Tracer;
+		};
+		4F78DAF213B643610032E0F3 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_OPTIMIZATION_LEVEL = "$(DEBUG_OPTIMIZE)";
+				PRODUCT_NAME = "AllOSX_32&64_intel";
+			};
+			name = Debug;
+		};
+		4F78DAF313B643610032E0F3 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				GCC_ENABLE_FIX_AND_CONTINUE = NO;
+				PRODUCT_NAME = "AllOSX_32&64_intel";
+				ZERO_LINK = NO;
+			};
+			name = Release;
+		};
+		4F78DAF413B643610032E0F3 /* Tracer */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = "AllOSX_32&64_intel";
+			};
+			name = Tracer;
+		};
+		4F7F5C6513E95EC8002918FD /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 4F7F5CAB13E9607A002918FD /* CommonDebugSettings.xcconfig */;
+			buildSettings = {
+				ARCHS = i386;
+				CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+				DSTROOT = "$(RTAS_FOLDER)";
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					$DEBUG_DEFS,
+					"_DEBUG=1",
+				);
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(inherited)",
+					"$(RTAS_DEFS)",
+				);
+				GCC_VERSION = "$(COMPILER)";
+				GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
+				GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = NO;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_ABOUT_POINTER_SIGNEDNESS = NO;
+				GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO;
+				GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+				GCC_WARN_UNKNOWN_PRAGMAS = NO;
+				GCC_WARN_UNUSED_VARIABLE = NO;
+				HEADER_SEARCH_PATHS = (
+					"$(ADDITIONAL_INCLUDES)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-RTAS-Info.plist";
+				LIBRARY_SEARCH_PATHS = (
+					"$(ADDITIONAL_LIBRARY_PATHS)",
+					"\"$(SRCROOT)/../../PT9_SDK/MacBag/Libs/Debug\"",
+					"\"$(SRCROOT)/../../PT9_SDK/MacBag/Libs/Release\"",
+				);
+				MacBag = "$(PT9_SDK)/MacBag";
+				OBJROOT = "build-mac";
+				OTHER_CFLAGS = "-fno-inline";
+				OTHER_LDFLAGS = (
+					"$(inherited)",
+					"\"-LlibPluginLibrary\"",
+				);
+				SDKROOT = "$(BASE_SDK)";
+				SKIP_INSTALL = NO;
+				SYMROOT = "build-mac";
+				VALID_ARCHS = i386;
+				WARNING_CFLAGS = (
+					"-Wno-reorder",
+					"-Wno-four-char-constants",
+				);
+				WRAPPER_EXTENSION = dpm;
+			};
+			name = Debug;
+		};
+		4F7F5C6613E95EC8002918FD /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 4F7F5CAC13E9607A002918FD /* CommonReleaseSettings.xcconfig */;
+			buildSettings = {
+				ARCHS = i386;
+				CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+				DEPLOYMENT_POSTPROCESSING = NO;
+				DSTROOT = "$(RTAS_FOLDER)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(RTAS_DEFS)",
+					"$(inherited)",
+				);
+				GCC_VERSION = "$(COMPILER)";
+				GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
+				GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = NO;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_ABOUT_POINTER_SIGNEDNESS = NO;
+				GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO;
+				GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+				GCC_WARN_UNKNOWN_PRAGMAS = NO;
+				GCC_WARN_UNUSED_VARIABLE = NO;
+				HEADER_SEARCH_PATHS = (
+					"$(ADDITIONAL_INCLUDES)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-RTAS-Info.plist";
+				LIBRARY_SEARCH_PATHS = (
+					"$(ADDITIONAL_LIBRARY_PATHS)",
+					"\"$(SRCROOT)/../../PT9_SDK/MacBag/Libs/Release\"",
+					"\"$(SRCROOT)/../../PT9_SDK/MacBag/Libs/Debug\"",
+				);
+				MacBag = "$(PT9_SDK)/MacBag";
+				OBJROOT = "build-mac";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "$(inherited)";
+				SDKROOT = "$(BASE_SDK)";
+				SKIP_INSTALL = NO;
+				SYMROOT = "build-mac";
+				VALID_ARCHS = i386;
+				WARNING_CFLAGS = (
+					"-Wno-reorder",
+					"-Wno-four-char-constants",
+				);
+				WRAPPER_EXTENSION = dpm;
+			};
+			name = Release;
+		};
+		4F7F5C6713E95EC8002918FD /* Tracer */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 4F7F5CAC13E9607A002918FD /* CommonReleaseSettings.xcconfig */;
+			buildSettings = {
+				ARCHS = i386;
+				CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+				DSTROOT = "$(RTAS_FOLDER)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(inherited)",
+					"$(RTAS_DEFS)",
+				);
+				GCC_VERSION = "$(COMPILER)";
+				GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
+				GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = NO;
+				GCC_WARN_ABOUT_POINTER_SIGNEDNESS = NO;
+				GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO;
+				GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
+				GCC_WARN_UNKNOWN_PRAGMAS = NO;
+				GCC_WARN_UNUSED_VARIABLE = NO;
+				HEADER_SEARCH_PATHS = (
+					"$(ADDITIONAL_INCLUDES)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-RTAS-Info.plist";
+				LIBRARY_SEARCH_PATHS = (
+					"$(ADDITIONAL_LIBRARY_PATHS)",
+					"\"$(SRCROOT)/../../PT9_SDK/MacBag/Libs/Release\"",
+					"\"$(SRCROOT)/../../PT9_SDK/MacBag/Libs/Debug\"",
+				);
+				MacBag = "$(PT9_SDK)/MacBag";
+				OBJROOT = "build-mac";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = (
+					"$(inherited)",
+					"\"-LlibPluginLibrary\"",
+				);
+				SDKROOT = "$(BASE_SDK)";
+				SYMROOT = "build-mac";
+				VALID_ARCHS = i386;
+				WARNING_CFLAGS = (
+					"-Wno-reorder",
+					"-Wno-four-char-constants",
+				);
+				WRAPPER_EXTENSION = dpm;
+			};
+			name = Tracer;
+		};
+		4F9828DD140A9EB700F3FCC1 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DSTROOT = "$(VST3_FOLDER)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(VST3_DEFS)",
+					"$(inherited)",
+				);
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(VST3_SDK)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-VST3-Info.plist";
+				SKIP_INSTALL = NO;
+				WRAPPER_EXTENSION = vst3;
+			};
+			name = Debug;
+		};
+		4F9828DE140A9EB700F3FCC1 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DSTROOT = "$(VST3_FOLDER)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(VST3_DEFS)",
+					"$(inherited)",
+				);
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(VST3_SDK)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-VST3-Info.plist";
+				SKIP_INSTALL = NO;
+				WRAPPER_EXTENSION = vst3;
+			};
+			name = Release;
+		};
+		4F9828DF140A9EB700F3FCC1 /* Tracer */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DSTROOT = "$(VST3_FOLDER)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(VST3_DEFS)",
+					"$(inherited)",
+				);
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(VST3_SDK)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-VST3-Info.plist";
+				SKIP_INSTALL = NO;
+				WRAPPER_EXTENSION = vst3;
+			};
+			name = Tracer;
+		};
+		4FB600301567CB0A0020189A /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 4F4CC38C1549B92900A9EA21 /* CommonDebugSettings.xcconfig */;
+			buildSettings = {
+				AAX_SDK_ROOT = "$(AAX_SDK)";
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				DEPLOYMENT_LOCATION = YES;
+				DSTROOT = "$(AAX_FOLDER)";
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = $IPLUG_PATH/IPlug_Prefix.pch;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					$DEBUG_DEFS,
+					"_DEBUG=1",
+				);
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(AAX_DEFS)",
+					"$(inherited)",
+				);
+				GCC_VERSION = "$(COMPILER)";
+				GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO;
+				HEADER_SEARCH_PATHS = (
+					"$(IPLUG_PATH)",
+					"$(ADDITIONAL_INCLUDES)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-AAX-Info.plist";
+				LIBRARY_SEARCH_PATHS = (
+					"$(ADDITIONAL_LIBRARY_PATHS)",
+					"$(SRCROOT)/../../AAX_SDK/Libs/Debug",
+				);
+				SDKROOT = "$(BASE_SDK)";
+				SKIP_INSTALL = NO;
+				WARNING_CFLAGS = (
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				WRAPPER_EXTENSION = aaxplugin;
+			};
+			name = Debug;
+		};
+		4FB600311567CB0A0020189A /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 4F4CC38D1549B92900A9EA21 /* CommonReleaseSettings.xcconfig */;
+			buildSettings = {
+				AAX_SDK_ROOT = "$(AAX_SDK)";
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				DEPLOYMENT_LOCATION = YES;
+				DEPLOYMENT_POSTPROCESSING = NO;
+				DSTROOT = "$(AAX_FOLDER)";
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = $IPLUG_PATH/IPlug_Prefix.pch;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					$RELEASE_DEFS,
+					"_NDEBUG=1",
+				);
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(AAX_DEFS)",
+					"$(inherited)",
+				);
+				GCC_VERSION = "$(COMPILER)";
+				GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO;
+				HEADER_SEARCH_PATHS = (
+					"$(IPLUG_PATH)",
+					"$(ADDITIONAL_INCLUDES)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-AAX-Info.plist";
+				LIBRARY_SEARCH_PATHS = (
+					"$(ADDITIONAL_LIBRARY_PATHS)",
+					"$(SRCROOT)/../../AAX_SDK/Libs/Release",
+				);
+				PREBINDING = YES;
+				SDKROOT = "$(BASE_SDK)";
+				SKIP_INSTALL = NO;
+				WARNING_CFLAGS = (
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				WRAPPER_EXTENSION = aaxplugin;
+			};
+			name = Release;
+		};
+		4FB600321567CB0A0020189A /* Tracer */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 4F4CC38D1549B92900A9EA21 /* CommonReleaseSettings.xcconfig */;
+			buildSettings = {
+				AAX_SDK_ROOT = "$(AAX_SDK)";
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				DEPLOYMENT_LOCATION = YES;
+				DEPLOYMENT_POSTPROCESSING = NO;
+				DSTROOT = "$(AAX_FOLDER)";
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = $IPLUG_PATH/IPlug_Prefix.pch;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					$TRACER_DEFS,
+					"_NDEBUG=1",
+				);
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(AAX_DEFS)",
+					"$(inherited)",
+				);
+				GCC_VERSION = "$(COMPILER)";
+				GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
+				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = NO;
+				HEADER_SEARCH_PATHS = (
+					"$(IPLUG_PATH)",
+					"$(ADDITIONAL_INCLUDES)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-AAX-Info.plist";
+				LIBRARY_SEARCH_PATHS = (
+					"$(ADDITIONAL_LIBRARY_PATHS)",
+					"$(SRCROOT)/../../AAX_SDK/Libs/Release",
+				);
+				SDKROOT = "$(BASE_SDK)";
+				SKIP_INSTALL = NO;
+				WARNING_CFLAGS = (
+					"-Wno-four-char-constants",
+					"-Wno-unknown-pragmas",
+				);
+				WRAPPER_EXTENSION = aaxplugin;
+			};
+			name = Tracer;
+		};
+		4FD16A0C13B63082001D0217 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DSTROOT = "$(APP_FOLDER)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(APP_DEFS)",
+					"$(inherited)",
+				);
+				HEADER_SEARCH_PATHS = (
+					"$(ADDITIONAL_APP_INCLUDES)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-OSXAPP-Info.plist";
+				OTHER_LDFLAGS = (
+					"-framework",
+					Foundation,
+					"-framework",
+					AppKit,
+				);
+				PREBINDING = NO;
+				SKIP_INSTALL = NO;
+				WRAPPER_EXTENSION = app;
+			};
+			name = Debug;
+		};
+		4FD16A0D13B63082001D0217 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DSTROOT = "$(APP_FOLDER)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(APP_DEFS)",
+					"$(inherited)",
+				);
+				HEADER_SEARCH_PATHS = (
+					"$(ADDITIONAL_APP_INCLUDES)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-OSXAPP-Info.plist";
+				OTHER_LDFLAGS = (
+					"-framework",
+					Foundation,
+					"-framework",
+					AppKit,
+				);
+				PREBINDING = NO;
+				SKIP_INSTALL = NO;
+				WRAPPER_EXTENSION = app;
+			};
+			name = Release;
+		};
+		4FD16A0E13B63082001D0217 /* Tracer */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DSTROOT = "$(APP_FOLDER)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = (
+					"$(APP_DEFS)",
+					"$(inherited)",
+				);
+				HEADER_SEARCH_PATHS = (
+					"$(ADDITIONAL_APP_INCLUDES)",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "resources/AccessiblePeakMeter-OSXAPP-Info.plist";
+				OTHER_LDFLAGS = (
+					"-framework",
+					Foundation,
+					"-framework",
+					AppKit,
+				);
+				PREBINDING = NO;
+				SKIP_INSTALL = NO;
+				WRAPPER_EXTENSION = app;
+			};
+			name = Tracer;
+		};
+		528359A90D7F0C3A00577159 /* Tracer */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 4FCF15AF133124D1009A6277 /* AccessiblePeakMeter.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+				DEPLOYMENT_LOCATION = YES;
+				EXECUTABLE_EXTENSION = "";
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_OPTIMIZATION_LEVEL = "$(RELEASE_OPTIMIZE)";
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = $IPLUG_PATH/IPlug_Prefix.pch;
+				GCC_PREPROCESSOR_DEFINITIONS = "$(TRACER_DEFS)";
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = "$(COCOA_DEFS)";
+				GCC_VERSION = "$(COMPILER)";
+				GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				GENERATE_PKGINFO_FILE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(IPLUG_PATH)",
+					"$(ADDITIONAL_INCLUDES)",
+				);
+				INFOPLIST_EXPAND_BUILD_SETTINGS = YES;
+				INFOPLIST_PREPROCESS = NO;
+				INSTALL_GROUP = admin;
+				INSTALL_OWNER = root;
+				INSTALL_PATH = /;
+				LIBRARY_SEARCH_PATHS = "$(ADDITIONAL_LIBRARY_PATHS)";
+				OTHER_CPLUSPLUSFLAGS = (
+					"$(OTHER_CFLAGS)",
+					"$(GCC_CFLAGS)",
+				);
+				PREBINDING = NO;
+				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
+				PRODUCT_NAME = "$(BINARY_NAME)";
+				SDKROOT = "$(BASE_SDK)";
+				SKIP_INSTALL = NO;
+				SYMROOT = "build-mac";
+				VALID_ARCHS = "i386 x86_64";
+				WRAPPER_EXTENSION = "";
+			};
+			name = Tracer;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "AccessiblePeakMeter" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				1DEB913F08733D840010E9CD /* Debug */,
+				1DEB914008733D840010E9CD /* Release */,
+				528359A90D7F0C3A00577159 /* Tracer */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4F20EF2F132C69FE0030E34C /* Build configuration list for PBXNativeTarget "VST2" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4F20EF30132C69FE0030E34C /* Debug */,
+				4F20EF31132C69FE0030E34C /* Release */,
+				4F20EF32132C69FE0030E34C /* Tracer */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4F3AE1DC12C0E5E2001FD7A4 /* Build configuration list for PBXNativeTarget "AU" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4F3AE1DD12C0E5E2001FD7A4 /* Debug */,
+				4F3AE1DE12C0E5E2001FD7A4 /* Release */,
+				4F3AE1DF12C0E5E2001FD7A4 /* Tracer */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4F78DAFD13B643940032E0F3 /* Build configuration list for PBXAggregateTarget "All" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4F78DAF213B643610032E0F3 /* Debug */,
+				4F78DAF313B643610032E0F3 /* Release */,
+				4F78DAF413B643610032E0F3 /* Tracer */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4F7F5C6413E95EC8002918FD /* Build configuration list for PBXNativeTarget "RTAS" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4F7F5C6513E95EC8002918FD /* Debug */,
+				4F7F5C6613E95EC8002918FD /* Release */,
+				4F7F5C6713E95EC8002918FD /* Tracer */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4F9828DC140A9EB700F3FCC1 /* Build configuration list for PBXNativeTarget "VST3" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4F9828DD140A9EB700F3FCC1 /* Debug */,
+				4F9828DE140A9EB700F3FCC1 /* Release */,
+				4F9828DF140A9EB700F3FCC1 /* Tracer */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4FB6002F1567CB0A0020189A /* Build configuration list for PBXNativeTarget "AAX" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4FB600301567CB0A0020189A /* Debug */,
+				4FB600311567CB0A0020189A /* Release */,
+				4FB600321567CB0A0020189A /* Tracer */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4FD16A0F13B63082001D0217 /* Build configuration list for PBXNativeTarget "APP" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4FD16A0C13B63082001D0217 /* Debug */,
+				4FD16A0D13B63082001D0217 /* Release */,
+				4FD16A0E13B63082001D0217 /* Tracer */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 089C1669FE841209C02AAC07 /* Project object */;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AccessiblePeakMeter_controls.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,186 @@
+// 
+// AccessiblePeakMeter_controls.h
+//
+// Author: Fiore Martin 
+// Started from IPlugMultiTargets example in WDL-OL, by Oli Larkin - https://github.com/olilarkin/wdl-ol
+//
+// Licensed under the Cockos WDL License, see README.txt
+//
+
+
+/* Knob with a text label and a text displaying the current value */
+class IKnobMultiControlText : public IKnobControl
+{
+private:
+  IRECT mDisplayRECT, mImgRECT, mNameRECT, mLabelRECT;
+  IBitmap mBitmap;
+
+public:
+  IKnobMultiControlText(IPlugBase* pPlug, IRECT pR, int paramIdx, IBitmap* pBitmap, IText* pText, int indent = 10)
+    : IKnobControl(pPlug, pR, paramIdx), mBitmap(*pBitmap)
+  {
+    mText = *pText;
+	/* mRECT is the bounding rectangle of the whole KnobMultiControlText */
+	mNameRECT = IRECT(mRECT.L, mRECT.T,mRECT.R, mRECT.T+16);
+    mDisplayRECT = IRECT(mRECT.L, mRECT.B-25, mRECT.R-21, mRECT.B); // left, top, right, bottom
+	mLabelRECT = mDisplayRECT;
+	mLabelRECT.L = mDisplayRECT.R; // shift it to the right of the diplay RECT
+	mLabelRECT.R = mLabelRECT.L+indent; // how much the display is indented 
+    mImgRECT = IRECT(mRECT.L, mRECT.T+16, &mBitmap);
+    mDisablePrompt = false;
+  }
+
+  ~IKnobMultiControlText() {}
+
+  bool Draw(IGraphics* pGraphics)
+  {
+    int i = 1 + int(0.5 + mValue * (double) (mBitmap.N - 1));
+    i = BOUNDED(i, 1, mBitmap.N);
+    
+	/* draw the knob */
+	pGraphics->DrawBitmap(&mBitmap, &mImgRECT, i, &mBlend);
+    
+	/* draw displayed value for host, that is the value as represented in the host */
+    char displayedValue[20];
+	mPlug->GetParam(mParamIdx)->GetDisplayForHost(displayedValue);
+
+	bool dispDrawn = true;
+	if (CSTR_NOT_EMPTY(displayedValue)) {
+		dispDrawn = pGraphics->DrawIText(&mText, displayedValue, &mDisplayRECT);
+    }
+
+	/* name of the parameter */
+	if (CSTR_NOT_EMPTY(mPlug->GetParam(mParamIdx)->GetNameForHost())){
+		char nameDisp[MAX_PARAM_NAME_LEN];
+		strcpy(nameDisp, mPlug->GetParam(mParamIdx)->GetNameForHost());
+
+		if (CSTR_NOT_EMPTY(mPlug->GetParam(mParamIdx)->GetLabelForHost())){
+			char label[MAX_PARAM_LABEL_LEN];
+			strcpy(label, mPlug->GetParam(mParamIdx)->GetLabelForHost());
+			pGraphics->DrawIText(&mText, label, &mLabelRECT);
+		}
+
+		return dispDrawn && pGraphics->DrawIText(&mText, nameDisp, &mNameRECT);
+	}
+
+    return dispDrawn;
+  }
+
+  void OnMouseDown(int x, int y, IMouseMod* pMod)
+  {
+	OnMouseDrag(x, y, 0, 0, pMod);	  
+  }
+
+  /* double click puts it back to default value */
+  void OnMouseDblClick(int x, int y, IMouseMod* pMod)
+  {
+    if (mDefaultValue >= 0.0)
+    {
+      mValue = mDefaultValue;
+      SetDirty();
+    }
+  }
+
+};
+
+/* Fader for the vertical peak level meter. It includes a text displaying the fader's current value in dB */
+class IFaderVertText : public IFaderControl
+{
+	ITextControl *mDisplayText;
+
+public :
+	IFaderVertText(IPlugBase *pPlug, int x, int y, int len, int paramIdx, IBitmap *pBitmap, ITextControl* pText)
+		: IFaderControl(pPlug, x, y, len, paramIdx, pBitmap), mDisplayText(pText)
+	{
+		makeDisplayText();
+	}
+
+	~IFaderVertText() {}
+
+	void OnMouseDown(int x, int y, IMouseMod* pMod)
+	{
+		// empty method override avoids IFaderControl::SnapToMouse(x, y);
+	}
+
+	void OnMouseDblClick(int x, int y, IMouseMod *pMod){
+		IFaderControl::OnMouseDblClick(x, y, pMod);
+		makeDisplayText();
+	}
+
+	void OnMouseDrag(int x, int y, int dX, int dY, IMouseMod* pMod){
+		IFaderControl::OnMouseDrag(x, y, dX, dY, pMod);
+		makeDisplayText();
+	}
+
+	/* changes the display text upon mouse dragging. If a value is passed 
+	   it is used for display else it's retrieved from the member value of this control.
+	   Passing an explicit value fixes an uncorrect update in SetValueFromPlug.
+	   The GUI update was in fact one step behind the update in the Daw.
+	*/
+	void makeDisplayText(const double* value = NULL) {
+		char textDisplay[MAX_PARAM_LABEL_LEN + MAX_PARAM_DISPLAY_LEN+1];
+
+		if (value == NULL){
+			mPlug->GetParam(mParamIdx)->GetDisplayForHost(textDisplay);
+		}
+		else{
+			mPlug->GetParam(mParamIdx)->GetDisplayForHost(*value, true, textDisplay, true);
+		}
+		strcat(textDisplay, " ");
+		strcat(textDisplay, mPlug->GetParam(mParamIdx)->GetLabelForHost());
+		mDisplayText->SetTextFromPlug(textDisplay);
+	}
+
+	/* This updates the GUI when the parameter is set from the Daw */
+	virtual void SetValueFromPlug(double value) {
+		IFaderControl::SetValueFromPlug(value);
+
+		makeDisplayText(&value);
+	}
+};
+
+/* Peak meter gauge. Doesn't control any parameter,
+   only shows the audio level in dB. Orientation is vertical 
+ */
+class IPeakMeterVert : public IControl
+{
+
+public:
+
+  IPeakMeterVert(IPlugBase* pPlug, IRECT pR, double defaultValueNormalized)
+	  : IControl(pPlug, pR)
+  {
+	mColor = IColor (255, 0, 35, 150);
+	mDefaultValue = defaultValueNormalized;
+  }
+
+  ~IPeakMeterVert() {}
+
+  
+
+  bool Draw(IGraphics* pGraphics)
+  {
+
+	/* big rectangle for the border */
+    IRECT paddedRect = mRECT.GetPadded(1);
+	pGraphics->DrawRect(&COLOR_GRAY, &(paddedRect));
+
+	/* now fill everything red*/
+	pGraphics->FillIRect(&COLOR_RED, &mRECT);
+
+	/* now fill with blue the part where the peak meter doesn't reach */
+	IRECT filledBit = IRECT(mRECT.L, mRECT.T, mRECT.R, mRECT.B - (mValue * mRECT.H()));
+    pGraphics->FillIRect(&mColor, &filledBit);
+	IRECT shade = IRECT(mRECT.L, mRECT.T, mRECT.L+1, mRECT.B - (mValue * mRECT.H()));
+	pGraphics->FillIRect(&COLOR_BLUE, &shade);
+	
+	pGraphics->DrawHorizontalLine(&COLOR_YELLOW, mRECT.B + 1 - (mDefaultValue * mRECT.H()), mRECT.L, mRECT.R - 1);
+    return true;
+  }
+
+  bool IsDirty() { return true;}
+
+protected:
+  IColor mColor;
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.txt	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,77 @@
+
+
+AccessiblePeakMeter2S is a hack of AccessiblePeakMeter that always plays the
+sonification in the system default sound card.
+For more info see the following links: 
+http://depic.eecs.qmul.ac.uk/apm/apm2s.html
+https://code.soundsoftware.ac.uk/projects/apm
+
+
+AccessiblePeakMeter2S is an audio processor that sonifies the level of the input
+audio by adding a pitch-modulated sine wave on top of it, and so makes the 
+peak meter gauge accessible to visually impaired users.
+
+AccessiblePeakMeter2S comes as a VST plugin for Windows (32/64) and Mac as well as AU plugin for Mac. 
+
+The plugin was developed in 2014/2015 at Queen Mary University of London as part of the 
+Design Patterns for Inclusive Collaboration research project ( http://depic.eecs.qmul.ac.uk ) 
+led by Dr. Nick Bryan-Kinns. All the coding was done by Fiore Martin. 
+
+The code uses the WDL / IPlug - Oli Larkin Edition (WDL-OL) framework, available
+at https://github.com/olilarkin/wdl-ol and it shares its license. 
+The license and more information about the framework are reported below.
+The code of AccessiblePeakMeter2S was started from the IPlugMultiTarget project in WDL-OL's IPlugExamples directory. 
+
+The WDL-OL specific commit used for development is available here: https://github.com/olilarkin/wdl-ol/commit/bfe87d2c4297d003f2475dc22d460440e5e1b4fa
+The whole framework code of this commit is available as a zip file (WDL-OL.zip) in the Downloads section of this repository and it differs slightly from the original WDL-OL version.
+
+The modification can be reproduced from the original WDL-OL commit by applying the following patch to WDL/IPlug/IControl.cpp
+
+251c251,252
+<   SetDirty();
+---
+>   if (!IsDirty())
+> 	SetDirty();
+
+In order to build AccessiblePeakMeter2S, extract WDL_OL.zip or clone WDL-OL from
+github, then place the code versioned in this repository into WDL-OL/IPlugExamples/AccessiblePeakMeter2S. 
+
+
+
+---------------- WDL-OL license and information ----------------
+
+WDL / IPlug - Oli Larkin Edition
+
+IPlug is a simple-to-use C++ framework for developing cross platform audio plugins and targeting multiple plugin APIs with the same code. Originally developed by Schwa/Cockos, IPlug has been enhanced by various contributors. IPlug depends on WDL, and that is why this project is called WDL-OL,  although most of the differences from Cockos' WDL are to do with IPlug.
+This version of IPlug targets VST2, VST3, AudioUnit RTAS and AAX (Native) APIs. It can also produce standalone Windows/OSX audio/midi apps and apps for Apple's IOS devices. 
+
+This version of WDL/IPlug shares the same license as the Cockos edition. Several of the added features are based on the work of other people. See individual source code files for any extra license information.
+
+Cockos WDL Page: http://www.cockos.com/wdl
+
+Discuss WDL on the WDL forum http://forum.cockos.com/forumdisplay.php?f=32
+
+------------------------------------------------
+
+Cockos WDL License
+
+Copyright (C) 2005 and later Cockos Incorporated
+
+Portions copyright other contributors, see each source file for more information
+
+This software is provided 'as-is', without any express or implied warranty.  In no event will the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+1. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+1. This notice may not be removed or altered from any source distribution.
+
+WDL includes the following 3rd party libraries (which are all similarly licensed):
+
+* JNetLib http://www.nullsoft.com/free/jnetlib
+* LibPNG http://www.libpng.org/pub/png
+* GifLib http://sourceforge.net/projects/libungif
+* JPEGLib http://www.ijg.org
+* zlib http://www.zlib.net
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app_wrapper/app_dialog.cpp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,570 @@
+#include "app_main.h"
+
+#ifdef OS_WIN
+#include "asio.h"
+#endif
+
+const int kNumIOVSOptions = 9;
+const int kNumSIGVSOptions = 7;
+
+const std::string kIOVSOptions[kNumIOVSOptions] = {"32", "64", "128", "256", "512", "1024", "2048", "4096", "8192" };
+const std::string kSIGVSOptions[kNumSIGVSOptions] = {"16", "32", "64", "128", "256", "512", "1024" };
+
+// check the input and output devices, find matching srs
+void PopulateSampleRateList(HWND hwndDlg, RtAudio::DeviceInfo* inputDevInfo, RtAudio::DeviceInfo* outputDevInfo)
+{
+  char buf[20];
+
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_SR,CB_RESETCONTENT,0,0);
+
+  std::vector<int> matchedSRs;
+
+  for (int i=0; i<inputDevInfo->sampleRates.size(); i++)
+  {
+    for (int j=0; j<outputDevInfo->sampleRates.size(); j++)
+    {
+      if(inputDevInfo->sampleRates[i] == outputDevInfo->sampleRates[j])
+        matchedSRs.push_back(inputDevInfo->sampleRates[i]);
+    }
+  }
+
+  for (int k=0; k<matchedSRs.size(); k++)
+  {
+    wsprintf(buf,"%i",matchedSRs[k]);
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_SR,CB_ADDSTRING,0,(LPARAM)buf);
+  }
+
+  LRESULT sridx = SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_SR, CB_FINDSTRINGEXACT, -1, (LPARAM)gState->mAudioSR);
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_SR,CB_SETCURSEL, sridx, 0);
+}
+
+void PopulateAudioInputList(HWND hwndDlg, RtAudio::DeviceInfo* info)
+{
+  char buf[20];
+
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_L,CB_RESETCONTENT,0,0);
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_R,CB_RESETCONTENT,0,0);
+
+  int i;
+
+  for (i=0; i<info->inputChannels -1; i++)
+  {
+//  for (int i=0; i<info.inputChannels; i++) {
+    wsprintf(buf,"%i",i+1);
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_L,CB_ADDSTRING,0,(LPARAM)buf);
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_R,CB_ADDSTRING,0,(LPARAM)buf);
+  }
+
+  // TEMP
+  wsprintf(buf,"%i",i+1);
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_R,CB_ADDSTRING,0,(LPARAM)buf);
+
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_L,CB_SETCURSEL, gState->mAudioInChanL - 1, 0);
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_R,CB_SETCURSEL, gState->mAudioInChanR - 1, 0);
+}
+
+void PopulateAudioOutputList(HWND hwndDlg, RtAudio::DeviceInfo* info)
+{
+  char buf[20];
+
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_L,CB_RESETCONTENT,0,0);
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_R,CB_RESETCONTENT,0,0);
+
+  int i;
+
+//  for (int i=0; i<info.outputChannels; i++) {
+  for (i=0; i<info->outputChannels -1; i++)
+  {
+
+    wsprintf(buf,"%i",i+1);
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_L,CB_ADDSTRING,0,(LPARAM)buf);
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_R,CB_ADDSTRING,0,(LPARAM)buf);
+  }
+
+  // TEMP
+  wsprintf(buf,"%i",i+1);
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_R,CB_ADDSTRING,0,(LPARAM)buf);
+
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_L,CB_SETCURSEL, gState->mAudioOutChanL - 1, 0);
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_R,CB_SETCURSEL, gState->mAudioOutChanR - 1, 0);
+}
+
+// This has to get called after any change to audio driver/in dev/out dev
+void PopulateDriverSpecificControls(HWND hwndDlg)
+{
+#ifdef OS_WIN
+  int driverType = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_DRIVER, CB_GETCURSEL, 0, 0);
+  if(driverType)   //ASIO
+  {
+    ComboBox_Enable(GetDlgItem(hwndDlg, IDC_COMBO_AUDIO_IN_DEV), FALSE);
+    Button_Enable(GetDlgItem(hwndDlg, IDC_BUTTON_ASIO), TRUE);
+  }
+  else
+  {
+    ComboBox_Enable(GetDlgItem(hwndDlg, IDC_COMBO_AUDIO_IN_DEV), TRUE);
+    Button_Enable(GetDlgItem(hwndDlg, IDC_BUTTON_ASIO), FALSE);
+  }
+#endif
+
+  int indevidx = 0;
+  int outdevidx = 0;
+
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_DEV,CB_RESETCONTENT,0,0);
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_DEV,CB_RESETCONTENT,0,0);
+
+  for (int i = 0; i<gAudioInputDevs.size(); i++)
+  {
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_DEV,CB_ADDSTRING,0,(LPARAM)GetAudioDeviceName(gAudioInputDevs[i]).c_str());
+
+    if(!strcmp(GetAudioDeviceName(gAudioInputDevs[i]).c_str(), gState->mAudioInDev))
+      indevidx = i;
+  }
+
+  for (int i = 0; i<gAudioOutputDevs.size(); i++)
+  {
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_DEV,CB_ADDSTRING,0,(LPARAM)GetAudioDeviceName(gAudioOutputDevs[i]).c_str());
+
+    if(!strcmp(GetAudioDeviceName(gAudioOutputDevs[i]).c_str(), gState->mAudioOutDev))
+      outdevidx = i;
+  }
+
+#ifdef OS_WIN
+  if(driverType)
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_DEV,CB_SETCURSEL, outdevidx, 0);
+  else
+#endif
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_DEV,CB_SETCURSEL, indevidx, 0);
+
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_DEV,CB_SETCURSEL, outdevidx, 0);
+
+  RtAudio::DeviceInfo inputDevInfo = gDAC->getDeviceInfo(gAudioInputDevs[indevidx]);
+  RtAudio::DeviceInfo outputDevInfo = gDAC->getDeviceInfo(gAudioOutputDevs[outdevidx]);
+
+  PopulateAudioInputList(hwndDlg, &inputDevInfo);
+  PopulateAudioOutputList(hwndDlg, &outputDevInfo);
+  PopulateSampleRateList(hwndDlg, &inputDevInfo, &outputDevInfo);
+}
+
+void PopulateAudioDialogs(HWND hwndDlg)
+{
+  PopulateDriverSpecificControls(hwndDlg);
+
+  if (gState->mAudioInIsMono)
+  {
+    SendDlgItemMessage(hwndDlg,IDC_CB_MONO_INPUT,BM_SETCHECK, BST_CHECKED,0);
+  }
+  else
+  {
+    SendDlgItemMessage(hwndDlg,IDC_CB_MONO_INPUT,BM_SETCHECK, BST_UNCHECKED,0);
+  }
+
+  //Populate IOVS combobox
+  for (int i = 0; i< kNumIOVSOptions; i++)
+  {
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IOVS,CB_ADDSTRING,0,(LPARAM)kIOVSOptions[i].c_str());
+  }
+
+  LRESULT iovsidx = SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_IOVS, CB_FINDSTRINGEXACT, -1, (LPARAM)gState->mAudioIOVS);
+  SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_IOVS, CB_SETCURSEL, iovsidx, 0);
+
+  //Populate SIGVS combobox
+  for (int i = 0; i< kNumSIGVSOptions; i++)
+  {
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_SIGVS,CB_ADDSTRING,0,(LPARAM)kSIGVSOptions[i].c_str());
+  }
+
+  LRESULT sigvsidx = SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_SIGVS, CB_FINDSTRINGEXACT, -1, (LPARAM)gState->mAudioSigVS);
+  SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_SIGVS, CB_SETCURSEL, sigvsidx, 0);
+}
+
+bool PopulateMidiDialogs(HWND hwndDlg)
+{
+  if ( !gMidiIn || !gMidiOut )
+    return false;
+  else
+  {
+    for (int i=0; i<gMIDIInputDevNames.size(); i++ )
+    {
+      SendDlgItemMessage(hwndDlg,IDC_COMBO_MIDI_IN_DEV,CB_ADDSTRING,0,(LPARAM)gMIDIInputDevNames[i].c_str());
+    }
+
+    LRESULT indevidx = SendDlgItemMessage(hwndDlg,IDC_COMBO_MIDI_IN_DEV,CB_FINDSTRINGEXACT, -1, (LPARAM)gState->mMidiInDev);
+
+    // if the midi port name wasn't found update the ini file, and set to off
+    if(indevidx == -1)
+    {
+      strcpy(gState->mMidiInDev, "off");
+      UpdateINI();
+      indevidx = 0;
+    }
+
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_MIDI_IN_DEV,CB_SETCURSEL, indevidx, 0);
+
+    for (int i=0; i<gMIDIOutputDevNames.size(); i++ )
+    {
+      SendDlgItemMessage(hwndDlg,IDC_COMBO_MIDI_OUT_DEV,CB_ADDSTRING,0,(LPARAM)gMIDIOutputDevNames[i].c_str());
+    }
+
+    LRESULT outdevidx = SendDlgItemMessage(hwndDlg,IDC_COMBO_MIDI_OUT_DEV,CB_FINDSTRINGEXACT, -1, (LPARAM)gState->mMidiOutDev);
+
+    // if the midi port name wasn't found update the ini file, and set to off
+    if(outdevidx == -1)
+    {
+      strcpy(gState->mMidiOutDev, "off");
+      UpdateINI();
+      outdevidx = 0;
+    }
+
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_MIDI_OUT_DEV,CB_SETCURSEL, outdevidx, 0);
+
+    // Populate MIDI channel dialogs
+
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_MIDI_IN_CHAN,CB_ADDSTRING,0,(LPARAM)"all");
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_MIDI_OUT_CHAN,CB_ADDSTRING,0,(LPARAM)"all");
+
+    char buf[20];
+
+    for (int i=0; i<16; i++)
+    {
+      wsprintf(buf,"%i",i+1);
+      SendDlgItemMessage(hwndDlg,IDC_COMBO_MIDI_IN_CHAN,CB_ADDSTRING,0,(LPARAM)buf);
+      SendDlgItemMessage(hwndDlg,IDC_COMBO_MIDI_OUT_CHAN,CB_ADDSTRING,0,(LPARAM)buf);
+    }
+
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_MIDI_IN_CHAN,CB_SETCURSEL, (LPARAM)gState->mMidiInChan, 0);
+    SendDlgItemMessage(hwndDlg,IDC_COMBO_MIDI_OUT_CHAN,CB_SETCURSEL, (LPARAM)gState->mMidiOutChan, 0);
+
+    return true;
+  }
+}
+
+#ifdef OS_WIN
+void PopulatePreferencesDialog(HWND hwndDlg)
+{
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_DRIVER,CB_ADDSTRING,0,(LPARAM)"DirectSound");
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_DRIVER,CB_ADDSTRING,0,(LPARAM)"ASIO");
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_DRIVER,CB_SETCURSEL, gState->mAudioDriverType, 0);
+
+  PopulateAudioDialogs(hwndDlg);
+  PopulateMidiDialogs(hwndDlg);
+}
+
+#else if defined OS_OSX
+void PopulatePreferencesDialog(HWND hwndDlg)
+{
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_DRIVER,CB_ADDSTRING,0,(LPARAM)"CoreAudio");
+  //SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_DRIVER,CB_ADDSTRING,0,(LPARAM)"Jack");
+  SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_DRIVER,CB_SETCURSEL, gState->mAudioDriverType, 0);
+
+  PopulateAudioDialogs(hwndDlg);
+  PopulateMidiDialogs(hwndDlg);
+}
+#endif
+
+WDL_DLGRET PreferencesDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+  int v = 0;
+  switch(uMsg)
+  {
+    case WM_INITDIALOG:
+
+      PopulatePreferencesDialog(hwndDlg);
+      memcpy(gTempState, gState, sizeof(AppState)); // copy state to temp state
+
+      return TRUE;
+
+    case WM_COMMAND:
+      switch (LOWORD(wParam))
+      {
+        case IDOK:
+          if(memcmp(gActiveState, gState, sizeof(AppState)) != 0) // if state is different try to change audio
+          {
+            TryToChangeAudio();
+          }
+          EndDialog(hwndDlg, IDOK); // INI file will be changed see MainDialogProc
+          break;
+        case IDAPPLY:
+          TryToChangeAudio();
+          break;
+        case IDCANCEL:
+          EndDialog(hwndDlg, IDCANCEL);
+
+          // if state has been changed reset to previous state, INI file won't be changed
+          if (!AudioSettingsInStateAreEqual(gState, gTempState)
+              || !MIDISettingsInStateAreEqual(gState, gTempState))
+          {
+            memcpy(gState, gTempState, sizeof(AppState));
+
+            TryToChangeAudioDriverType();
+            ProbeAudioIO();
+            TryToChangeAudio();
+          }
+
+          break;
+
+        case IDC_COMBO_AUDIO_DRIVER:
+          if (HIWORD(wParam) == CBN_SELCHANGE)
+          {
+
+            v = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_DRIVER, CB_GETCURSEL, 0, 0);
+
+            if(v != gState->mAudioDriverType)
+            {
+              gState->mAudioDriverType = v;
+
+              TryToChangeAudioDriverType();
+              ProbeAudioIO();
+
+              strcpy(gState->mAudioInDev,GetAudioDeviceName(gAudioInputDevs[0]).c_str());
+              strcpy(gState->mAudioOutDev,GetAudioDeviceName(gAudioOutputDevs[0]).c_str());
+
+              // Reset IO
+              gState->mAudioOutChanL = 1;
+              gState->mAudioOutChanR = 2;
+
+              PopulateAudioDialogs(hwndDlg);
+            }
+          }
+          break;
+
+        case IDC_COMBO_AUDIO_IN_DEV:
+          if (HIWORD(wParam) == CBN_SELCHANGE)
+          {
+            int idx = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_IN_DEV, CB_GETCURSEL, 0, 0);
+            SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_IN_DEV, CB_GETLBTEXT, idx, (LPARAM) gState->mAudioInDev);
+
+            // Reset IO
+            gState->mAudioInChanL = 1;
+            gState->mAudioInChanR = 2;
+
+            PopulateDriverSpecificControls(hwndDlg);
+          }
+          break;
+
+        case IDC_COMBO_AUDIO_OUT_DEV:
+          if (HIWORD(wParam) == CBN_SELCHANGE)
+          {
+            int idx = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_OUT_DEV, CB_GETCURSEL, 0, 0);
+            SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_OUT_DEV, CB_GETLBTEXT, idx, (LPARAM) gState->mAudioOutDev);
+
+            // Reset IO
+            gState->mAudioOutChanL = 1;
+            gState->mAudioOutChanR = 2;
+
+            PopulateDriverSpecificControls(hwndDlg);
+          }
+          break;
+
+        case IDC_COMBO_AUDIO_IN_L:
+          if (HIWORD(wParam) == CBN_SELCHANGE)
+          {
+            gState->mAudioInChanL = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_IN_L, CB_GETCURSEL, 0, 0) + 1;
+
+            //TEMP
+            gState->mAudioInChanR = gState->mAudioInChanL + 1;
+            SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_R,CB_SETCURSEL, gState->mAudioInChanR - 1, 0);
+            //
+          }
+          break;
+
+        case IDC_COMBO_AUDIO_IN_R:
+          if (HIWORD(wParam) == CBN_SELCHANGE)
+            SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_IN_R,CB_SETCURSEL, gState->mAudioInChanR - 1, 0);  // TEMP
+//                gState->mAudioInChanR = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_IN_R, CB_GETCURSEL, 0, 0);
+          break;
+
+        case IDC_COMBO_AUDIO_OUT_L:
+          if (HIWORD(wParam) == CBN_SELCHANGE)
+          {
+            gState->mAudioOutChanL = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_OUT_L, CB_GETCURSEL, 0, 0) + 1;
+
+            //TEMP
+            gState->mAudioOutChanR = gState->mAudioOutChanL + 1;
+            SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_R,CB_SETCURSEL, gState->mAudioOutChanR - 1, 0);
+            //
+          }
+          break;
+
+        case IDC_COMBO_AUDIO_OUT_R:
+          if (HIWORD(wParam) == CBN_SELCHANGE)
+            SendDlgItemMessage(hwndDlg,IDC_COMBO_AUDIO_OUT_R,CB_SETCURSEL, gState->mAudioOutChanR - 1, 0);  // TEMP
+//                gState->mAudioOutChanR = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_OUT_R, CB_GETCURSEL, 0, 0);
+          break;
+
+        case IDC_CB_MONO_INPUT:
+          if (SendDlgItemMessage(hwndDlg,IDC_CB_MONO_INPUT, BM_GETCHECK, 0, 0) == BST_CHECKED)
+            gState->mAudioInIsMono = 1;
+          else
+            gState->mAudioInIsMono = 0;
+          break;
+
+        case IDC_COMBO_AUDIO_IOVS: // follow through
+        case IDC_COMBO_AUDIO_SIGVS:
+          //TODO: FIX
+          if (HIWORD(wParam) == CBN_SELCHANGE)
+          {
+            int iovsidx = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_IOVS, CB_GETCURSEL, 0, 0);
+            int sigvsidx = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_SIGVS, CB_GETCURSEL, 0, 0);
+
+            if (atoi(kIOVSOptions[iovsidx].c_str()) < atoi(kSIGVSOptions[sigvsidx].c_str()))   // if iovs < sigvs
+            {
+              SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_IOVS, CB_GETLBTEXT, iovsidx, (LPARAM) gState->mAudioIOVS);
+              strcpy(gState->mAudioSigVS, kSIGVSOptions[0].c_str()); // set sigvs to minimum
+              SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_SIGVS, CB_SETCURSEL, -1, 0);
+            }
+            else
+            {
+              SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_IOVS, CB_GETLBTEXT, iovsidx, (LPARAM) gState->mAudioIOVS);
+              SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_SIGVS, CB_GETLBTEXT, sigvsidx, (LPARAM) gState->mAudioSigVS);
+            }
+          }
+          break;
+        case IDC_COMBO_AUDIO_SR:
+          if (HIWORD(wParam) == CBN_SELCHANGE)
+          {
+            int idx = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_SR, CB_GETCURSEL, 0, 0);
+            SendDlgItemMessage(hwndDlg, IDC_COMBO_AUDIO_SR, CB_GETLBTEXT, idx, (LPARAM) gState->mAudioSR);
+          }
+          break;
+
+        case IDC_BUTTON_ASIO:
+          if (HIWORD(wParam) == BN_CLICKED)
+            #ifdef OS_OSX
+            system("open \"/Applications/Utilities/Audio MIDI Setup.app\"");
+            #elif defined OS_WIN
+            if( gState->mAudioDriverType == DAC_ASIO && gDAC->isStreamRunning()) // TODO: still not right
+              ASIOControlPanel();
+            #endif
+          break;
+
+        case IDC_COMBO_MIDI_IN_DEV:
+          if (HIWORD(wParam) == CBN_SELCHANGE)
+          {
+            int idx = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_MIDI_IN_DEV, CB_GETCURSEL, 0, 0);
+            SendDlgItemMessage(hwndDlg, IDC_COMBO_MIDI_IN_DEV, CB_GETLBTEXT, idx, (LPARAM) gState->mMidiInDev);
+            ChooseMidiInput( gState->mMidiInDev );
+          }
+          break;
+
+        case IDC_COMBO_MIDI_OUT_DEV:
+          if (HIWORD(wParam) == CBN_SELCHANGE)
+          {
+            int idx = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_MIDI_OUT_DEV, CB_GETCURSEL, 0, 0);
+            SendDlgItemMessage(hwndDlg, IDC_COMBO_MIDI_OUT_DEV, CB_GETLBTEXT, idx, (LPARAM) gState->mMidiOutDev);
+            ChooseMidiOutput( gState->mMidiOutDev );
+          }
+          break;
+
+        case IDC_COMBO_MIDI_IN_CHAN:
+          if (HIWORD(wParam) == CBN_SELCHANGE)
+            gState->mMidiInChan = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_MIDI_IN_CHAN, CB_GETCURSEL, 0, 0);
+          break;
+
+        case IDC_COMBO_MIDI_OUT_CHAN:
+          if (HIWORD(wParam) == CBN_SELCHANGE)
+            gState->mMidiOutChan = (int) SendDlgItemMessage(hwndDlg, IDC_COMBO_MIDI_OUT_CHAN, CB_GETCURSEL, 0, 0);
+          break;
+
+        default:
+          break;
+      }
+      break;
+    default:
+      return FALSE;
+  }
+  return TRUE;
+}
+
+#ifdef _WIN32
+void ClientResize(HWND hWnd, int nWidth, int nHeight)
+{
+  RECT rcClient, rcWindow;
+  POINT ptDiff;
+  int screenwidth, screenheight;
+  int x, y;
+
+  screenwidth  = GetSystemMetrics(SM_CXSCREEN);
+  screenheight = GetSystemMetrics(SM_CYSCREEN);
+  x = (screenwidth / 2) - (nWidth/2);
+  y = (screenheight / 2) - (nHeight/2);
+
+  GetClientRect(hWnd, &rcClient);
+  GetWindowRect(hWnd, &rcWindow);
+  ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
+  ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
+  MoveWindow(hWnd, x, y, nWidth + ptDiff.x, nHeight + ptDiff.y, FALSE);
+}
+#endif
+
+WDL_DLGRET MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+  switch (uMsg)
+  {
+    case WM_INITDIALOG:
+
+      gHWND=hwndDlg;
+
+      if(!AttachGUI()) printf("couldn't attach gui\n");
+
+#ifdef _WIN32
+      ClientResize(hwndDlg, GUI_WIDTH, GUI_HEIGHT);
+      //SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON1)));
+      //SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON1)));
+
+#else // OSX
+      CenterWindow(hwndDlg);
+#endif
+
+      ShowWindow(hwndDlg,SW_SHOW);
+      return 1;
+    case WM_DESTROY:
+      gHWND=NULL;
+
+#ifdef _WIN32
+      PostQuitMessage(0);
+#else
+      SWELL_PostQuitMessage(hwndDlg);
+#endif
+
+      return 0;
+    case WM_CLOSE:
+      DestroyWindow(hwndDlg);
+      return 0;
+//    case WM_GETDLGCODE: {
+//        LPARAM lres;
+//        lres = CallWindowProc(/*TODO GET PROC */, hWnd, WM_GETDLGCODE, wParam, lParam);
+//        if (lParam && ((MSG*)lParam)->message == WM_KEYDOWN  &&  wParam == VK_LEFT) {
+//          lres |= DLGC_WANTMESSAGE;
+//        }
+//        return lres;
+//      }
+    case WM_COMMAND:
+      switch (LOWORD(wParam))
+      {
+        case ID_QUIT:
+          DestroyWindow(hwndDlg);
+          return 0;
+        case ID_ABOUT:
+          if(!gPluginInstance->HostRequestingAboutBox())
+          {
+            char version[50];
+            sprintf(version, BUNDLE_MFR"\nBuilt on "__DATE__);
+            MessageBox(hwndDlg,version, BUNDLE_NAME, MB_OK);
+          }
+          return 0;
+        case ID_PREFERENCES:
+        {
+          INT_PTR ret = DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG_PREF), hwndDlg, PreferencesDlgProc);
+
+          if(ret == IDOK)
+          {
+            UpdateINI();
+          }
+
+          return 0;
+        }
+      }
+      return 0;
+  }
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app_wrapper/app_main.cpp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,1056 @@
+#include "app_main.h"
+
+#ifdef OS_WIN
+  #include <windows.h>
+  #include <shlobj.h>
+  #include <sys/stat.h>
+#endif
+
+HWND gHWND;
+
+HINSTANCE gHINST;
+UINT gScrollMessage;
+IPlug* gPluginInstance;
+RtAudio* gDAC = 0;
+RtMidiIn *gMidiIn = 0;
+RtMidiOut *gMidiOut = 0;
+
+AppState *gState;
+AppState *gTempState;
+AppState *gActiveState;
+
+char *gINIPath = new char[200]; // path of ini file
+
+unsigned int gIOVS = 512;
+unsigned int gSigVS = 32;
+unsigned int gBufIndex = 0; // Loops 0 to SigVS
+unsigned int gVecElapsed = 0;
+double gFadeMult = 0.; // Fade multiplier
+
+std::vector<unsigned int> gAudioInputDevs;
+std::vector<unsigned int> gAudioOutputDevs;
+std::vector<std::string> gMIDIInputDevNames;
+std::vector<std::string> gMIDIOutputDevNames;
+std::vector<std::string> gAudioIDDevNames;
+
+void UpdateINI()
+{
+  char buf[100]; // temp buffer for writing integers to profile strings
+
+  sprintf(buf, "%u", gState->mAudioDriverType);
+  WritePrivateProfileString("audio", "driver", buf, gINIPath);
+
+  WritePrivateProfileString("audio", "indev", gState->mAudioInDev, gINIPath);
+  WritePrivateProfileString("audio", "outdev", gState->mAudioOutDev, gINIPath);
+
+  sprintf(buf, "%u", gState->mAudioInChanL);
+  WritePrivateProfileString("audio", "in1", buf, gINIPath);
+  sprintf(buf, "%u", gState->mAudioInChanR);
+  WritePrivateProfileString("audio", "in2", buf, gINIPath);
+  sprintf(buf, "%u", gState->mAudioOutChanL);
+  WritePrivateProfileString("audio", "out1", buf, gINIPath);
+  sprintf(buf, "%u", gState->mAudioOutChanR);
+  WritePrivateProfileString("audio", "out2", buf, gINIPath);
+  sprintf(buf, "%u", gState->mAudioInIsMono);
+  WritePrivateProfileString("audio", "monoinput", buf, gINIPath);
+
+  WritePrivateProfileString("audio", "iovs", gState->mAudioIOVS, gINIPath);
+  WritePrivateProfileString("audio", "sigvs", gState->mAudioSigVS, gINIPath);
+
+  WritePrivateProfileString("audio", "sr", gState->mAudioSR, gINIPath);
+
+  WritePrivateProfileString("midi", "indev", gState->mMidiInDev, gINIPath);
+  WritePrivateProfileString("midi", "outdev", gState->mMidiOutDev, gINIPath);
+
+  sprintf(buf, "%u", gState->mMidiInChan);
+  WritePrivateProfileString("midi", "inchan", buf, gINIPath);
+  sprintf(buf, "%u", gState->mMidiOutChan);
+  WritePrivateProfileString("midi", "outchan", buf, gINIPath);
+}
+
+// returns the device name. Core Audio device names are truncated
+std::string GetAudioDeviceName(int idx)
+{
+  return gAudioIDDevNames.at(idx);
+}
+
+// returns the rtaudio device ID, based on the (truncated) device name
+int GetAudioDeviceID(char* deviceNameToTest)
+{
+  TRACE;
+
+  for(int i = 0; i < gAudioIDDevNames.size(); i++)
+  {
+    if(!strcmp(deviceNameToTest, gAudioIDDevNames.at(i).c_str() ))
+      return i;
+  }
+
+  return -1;
+}
+
+unsigned int GetMIDIInPortNumber(const char* nameToTest)
+{
+  int start = 1;
+
+  if(!strcmp(nameToTest, "off")) return 0;
+
+  #ifdef OS_OSX
+  start = 2;
+  if(!strcmp(nameToTest, "virtual input")) return 1;
+  #endif
+
+  for (int i = 0; i < gMidiIn->getPortCount(); i++)
+  {
+    if(!strcmp(nameToTest, gMidiIn->getPortName(i).c_str()))
+      return (i + start);
+  }
+
+  return -1;
+}
+
+unsigned int GetMIDIOutPortNumber(const char* nameToTest)
+{
+  int start = 1;
+
+  if(!strcmp(nameToTest, "off")) return 0;
+
+  #ifdef OS_OSX
+  start = 2;
+  if(!strcmp(nameToTest, "virtual output")) return 1;
+  #endif
+
+  for (int i = 0; i < gMidiOut->getPortCount(); i++)
+  {
+    if(!strcmp(nameToTest, gMidiOut->getPortName(i).c_str()))
+      return (i + start);
+  }
+
+  return -1;
+}
+
+// find out which devices have input channels & which have output channels, add their ids to the lists
+void ProbeAudioIO()
+{
+  TRACE;
+
+  RtAudio::DeviceInfo info;
+
+  gAudioInputDevs.clear();
+  gAudioOutputDevs.clear();
+  gAudioIDDevNames.clear();
+
+  unsigned int nDevices = gDAC->getDeviceCount();
+
+  for (int i=0; i<nDevices; i++)
+  {
+    info = gDAC->getDeviceInfo(i);
+    std::string deviceName = info.name;
+
+    #ifdef OS_OSX
+    size_t colonIdx = deviceName.rfind(": ");
+
+    if(colonIdx != std::string::npos && deviceName.length() >= 2)
+      deviceName = deviceName.substr(colonIdx + 2, deviceName.length() - colonIdx - 2);
+
+    #endif
+
+    gAudioIDDevNames.push_back(deviceName);
+
+    if ( info.probed == false )
+      std::cout << deviceName << ": Probe Status = Unsuccessful\n";
+    else if ( !strcmp("Generic Low Latency ASIO Driver", deviceName.c_str() ))
+      std::cout << deviceName << ": Probe Status = Unsuccessful\n";
+    else
+    {
+      if(info.inputChannels > 0)
+        gAudioInputDevs.push_back(i);
+
+      if(info.outputChannels > 0)
+        gAudioOutputDevs.push_back(i);
+    }
+  }
+}
+
+void ProbeMidiIO()
+{
+  if ( !gMidiIn || !gMidiOut )
+    return;
+  else
+  {
+    int nInputPorts = gMidiIn->getPortCount();
+
+    gMIDIInputDevNames.push_back("off");
+
+    #ifndef OS_WIN
+    gMIDIInputDevNames.push_back("virtual input");
+    #endif
+
+    for (int i=0; i<nInputPorts; i++ )
+    {
+      gMIDIInputDevNames.push_back(gMidiIn->getPortName(i));
+    }
+
+    int nOutputPorts = gMidiOut->getPortCount();
+
+    gMIDIOutputDevNames.push_back("off");
+
+#ifndef _WIN32
+    gMIDIOutputDevNames.push_back("virtual output");
+#endif
+
+    for (int i=0; i<nOutputPorts; i++ )
+    {
+      gMIDIOutputDevNames.push_back(gMidiOut->getPortName(i));
+      //This means the virtual output port wont be added as an input
+    }
+  }
+}
+
+bool AudioSettingsInStateAreEqual(AppState* os, AppState* ns)
+{
+  if (os->mAudioDriverType != ns->mAudioDriverType) return false;
+  if (strcmp(os->mAudioInDev, ns->mAudioInDev)) return false;
+  if (strcmp(os->mAudioOutDev, ns->mAudioOutDev)) return false;
+  if (strcmp(os->mAudioSR, ns->mAudioSR)) return false;
+  if (strcmp(os->mAudioIOVS, ns->mAudioIOVS)) return false;
+  if (strcmp(os->mAudioSigVS, ns->mAudioSigVS)) return false;
+  if (os->mAudioInChanL != ns->mAudioInChanL) return false;
+  if (os->mAudioInChanR != ns->mAudioInChanR) return false;
+  if (os->mAudioOutChanL != ns->mAudioOutChanL) return false;
+  if (os->mAudioOutChanR != ns->mAudioOutChanR) return false;
+  if (os->mAudioInIsMono != ns->mAudioInIsMono) return false;
+
+  return true;
+}
+
+bool MIDISettingsInStateAreEqual(AppState* os, AppState* ns)
+{
+  if (strcmp(os->mMidiInDev, ns->mMidiInDev)) return false;
+  if (strcmp(os->mMidiOutDev, ns->mMidiOutDev)) return false;
+  if (os->mMidiInChan != ns->mMidiInChan) return false;
+  if (os->mMidiOutChan != ns->mMidiOutChan) return false;
+
+  return true;
+}
+
+void MIDICallback( double deltatime, std::vector< unsigned char > *message, void *userData )
+{
+  if ( message->size() )
+  {
+    IMidiMsg *myMsg;
+
+    switch (message->size())
+    {
+      case 1:
+        myMsg = new IMidiMsg(0, message->at(0), 0, 0);
+        break;
+      case 2:
+        myMsg = new IMidiMsg(0, message->at(0), message->at(1), 0);
+        break;
+      case 3:
+        myMsg = new IMidiMsg(0, message->at(0), message->at(1), message->at(2));
+        break;
+      default:
+        DBGMSG("NOT EXPECTING %d midi callback msg len\n", (int) message->size());
+        break;
+    }
+
+    IMidiMsg msg(*myMsg);
+
+    delete myMsg;
+
+    // filter midi messages based on channel, if gStatus.mMidiInChan != all (0)
+    if (gState->mMidiInChan)
+    {
+      if (gState->mMidiInChan == msg.Channel() + 1 )
+        gPluginInstance->ProcessMidiMsg(&msg);
+    }
+    else
+    {
+      gPluginInstance->ProcessMidiMsg(&msg);
+    }
+  }
+}
+
+int AudioCallback(void *outputBuffer,
+                  void *inputBuffer,
+                  unsigned int nFrames,
+                  double streamTime,
+                  RtAudioStreamStatus status,
+                  void *userData )
+{
+  if ( status )
+    std::cout << "Stream underflow detected!" << std::endl;
+
+  double* inputBufferD = (double*)inputBuffer;
+  double* outputBufferD = (double*)outputBuffer;
+
+  int inRightOffset = 0;
+
+  if(!gState->mAudioInIsMono)
+    inRightOffset = nFrames;
+
+  if (gVecElapsed > N_VECTOR_WAIT) // wait N_VECTOR_WAIT * iovs before processing audio, to avoid clicks
+  {
+    for (int i=0; i<nFrames; i++)
+    {
+      gBufIndex %= gSigVS;
+
+      if (gBufIndex == 0)
+      {
+        double* inputs[2] = {inputBufferD + i, inputBufferD + inRightOffset + i};
+        double* outputs[2] = {outputBufferD + i, outputBufferD + nFrames + i};
+
+        gPluginInstance->LockMutexAndProcessDoubleReplacing(inputs, outputs, gSigVS);
+      }
+
+      // fade in
+      if (gFadeMult < 1.)
+      {
+        gFadeMult += (1. / nFrames);
+      }
+
+      outputBufferD[i] *= gFadeMult;
+      outputBufferD[i + nFrames] *= gFadeMult;
+
+      outputBufferD[i] *= APP_MULT;
+      outputBufferD[i + nFrames] *= APP_MULT;
+
+      gBufIndex++;
+    }
+  }
+  else
+  {
+    memset(outputBuffer, 0, nFrames * 2 * sizeof(double));
+  }
+
+  gVecElapsed++;
+
+  return 0;
+}
+
+bool TryToChangeAudioDriverType()
+{
+  TRACE;
+
+  if (gDAC)
+  {
+    if (gDAC->isStreamOpen())
+    {
+      gDAC->closeStream();
+    }
+
+    DELETE_NULL(gDAC);
+  }
+
+#ifdef OS_WIN
+  if(gState->mAudioDriverType == DAC_ASIO)
+    gDAC = new RtAudio(RtAudio::WINDOWS_ASIO);
+  else
+    gDAC = new RtAudio(RtAudio::WINDOWS_DS);
+#elif defined OS_OSX
+  if(gState->mAudioDriverType == DAC_COREAUDIO)
+    gDAC = new RtAudio(RtAudio::MACOSX_CORE);
+  //else
+  //gDAC = new RtAudio(RtAudio::UNIX_JACK);
+#endif
+
+  if(gDAC)
+    return true;
+  else
+    return false;
+}
+
+bool TryToChangeAudio()
+{
+  TRACE;
+
+  int inputID = -1;
+  int outputID = -1;
+
+#ifdef OS_WIN
+  if(gState->mAudioDriverType == DAC_ASIO)
+    inputID = GetAudioDeviceID(gState->mAudioOutDev);
+  else
+    inputID = GetAudioDeviceID(gState->mAudioInDev);
+#else
+  inputID = GetAudioDeviceID(gState->mAudioInDev);
+#endif
+
+  outputID = GetAudioDeviceID(gState->mAudioOutDev);
+
+  int samplerate = atoi(gState->mAudioSR);
+  int iovs = atoi(gState->mAudioIOVS);
+
+  if (inputID != -1 && outputID != -1)
+  {
+    return InitialiseAudio(inputID, outputID, samplerate, iovs, NUM_CHANNELS, gState->mAudioInChanL - 1, gState->mAudioOutChanL - 1);
+  }
+
+  return false;
+}
+
+bool InitialiseAudio(unsigned int inId,
+                     unsigned int outId,
+                     unsigned int sr,
+                     unsigned int iovs,
+                     unsigned int chnls,
+                     unsigned int inChanL,
+                     unsigned int outChanL
+                    )
+{
+  TRACE;
+
+  if (gDAC->isStreamOpen())
+  {
+    if (gDAC->isStreamRunning())
+    {
+      try
+      {
+        gDAC->abortStream();
+      }
+      catch (RtError& e)
+      {
+        e.printMessage();
+      }
+    }
+
+    gDAC->closeStream();
+  }
+
+  RtAudio::StreamParameters iParams, oParams;
+  iParams.deviceId = inId;
+  iParams.nChannels = chnls;
+  iParams.firstChannel = inChanL;
+
+  oParams.deviceId = outId;
+  oParams.nChannels = chnls;
+  oParams.firstChannel = outChanL;
+
+  gIOVS = iovs; // gIOVS may get changed by stream
+  gSigVS = atoi(gState->mAudioSigVS); // This is done here so that it changes when the callback is stopped
+
+  DBGMSG("\ntrying to start audio stream @ %i sr, %i iovs, %i sigvs\nindev = %i:%s\noutdev = %i:%s\n", sr, iovs, gSigVS, inId, GetAudioDeviceName(inId).c_str(), outId, GetAudioDeviceName(outId).c_str());
+
+  RtAudio::StreamOptions options;
+  options.flags = RTAUDIO_NONINTERLEAVED;
+// options.streamName = BUNDLE_NAME; // JACK stream name, not used on other streams
+
+  gBufIndex = 0;
+  gVecElapsed = 0;
+  gFadeMult = 0.;
+
+  gPluginInstance->SetBlockSize(gSigVS);
+  gPluginInstance->SetSampleRate(sr);
+  gPluginInstance->Reset();
+
+  try
+  {
+    TRACE;
+    gDAC->openStream( &oParams, &iParams, RTAUDIO_FLOAT64, sr, &gIOVS, &AudioCallback, NULL, &options);
+    gDAC->startStream();
+
+    memcpy(gActiveState, gState, sizeof(AppState)); // copy state to active state
+  }
+  catch ( RtError& e )
+  {
+    e.printMessage();
+    return false;
+  }
+
+  return true;
+}
+
+bool InitialiseMidi()
+{
+  try
+  {
+    gMidiIn = new RtMidiIn();
+  }
+  catch ( RtError &error )
+  {
+    FREE_NULL(gMidiIn);
+    error.printMessage();
+    return false;
+  }
+
+  try
+  {
+    gMidiOut = new RtMidiOut();
+  }
+  catch ( RtError &error )
+  {
+    FREE_NULL(gMidiOut);
+    error.printMessage();
+    return false;
+  }
+
+  gMidiIn->setCallback( &MIDICallback );
+  gMidiIn->ignoreTypes( !ENABLE_SYSEX, !ENABLE_MIDICLOCK, !ENABLE_ACTIVE_SENSING );
+
+  return true;
+}
+
+bool ChooseMidiInput(const char* pPortName)
+{
+  unsigned int port = GetMIDIInPortNumber(pPortName);
+
+  if(port == -1)
+  {
+    strcpy(gState->mMidiInDev, "off");
+    UpdateINI();
+    port = 0;
+  }
+  /*
+  IMidiMsg msg;
+  msg.MakeControlChangeMsg(IMidiMsg::kAllNotesOff, 127, 0);
+
+  std::vector<unsigned char> message;
+  message.push_back( msg.mStatus );
+  message.push_back( msg.mData1 );
+  message.push_back( msg.mData2 );
+
+  gPluginInstance->ProcessMidiMsg(&msg);
+  */
+  if (gMidiIn)
+  {
+    gMidiIn->closePort();
+
+    if (port == 0)
+    {
+      return true;
+    }
+    #ifdef OS_WIN
+    else
+    {
+      gMidiIn->openPort(port-1);
+      return true;
+    }
+    #else
+    else if(port == 1)
+    {
+      std::string virtualMidiInputName = "To ";
+      virtualMidiInputName += BUNDLE_NAME;
+      gMidiIn->openVirtualPort(virtualMidiInputName);
+      return true;
+    }
+    else
+    {
+      gMidiIn->openPort(port-2);
+      return true;
+    }
+    #endif
+  }
+
+  return false;
+}
+
+bool ChooseMidiOutput(const char* pPortName)
+{
+  unsigned int port = GetMIDIOutPortNumber(pPortName);
+
+  if(port == -1)
+  {
+    strcpy(gState->mMidiOutDev, "off");
+    UpdateINI();
+    port = 0;
+  }
+
+  if (gMidiOut)
+  {
+    /*
+    IMidiMsg msg;
+    msg.MakeControlChangeMsg(IMidiMsg::kAllNotesOff, 127, 0);
+
+    std::vector<unsigned char> message;
+    message.push_back( msg.mStatus );
+    message.push_back( msg.mData1 );
+    message.push_back( msg.mData2 );
+
+    gMidiOut->sendMessage( &message );
+    */
+    gMidiOut->closePort();
+
+    if (port == 0)
+    {
+      return true;
+    }
+    #ifdef OS_WIN
+    else
+    {
+      gMidiOut->openPort(port-1);
+      return true;
+    }
+    #else
+    else if(port == 1)
+    {
+      std::string virtualMidiOutputName = "From ";
+      virtualMidiOutputName += BUNDLE_NAME;
+      gMidiOut->openVirtualPort(virtualMidiOutputName);
+      return true;
+    }
+    else
+    {
+      gMidiOut->openPort(port-2);
+      return true;
+    }
+    #endif
+  }
+
+  return false;
+}
+
+extern bool AttachGUI()
+{
+  IGraphics* pGraphics = gPluginInstance->GetGUI();
+
+  if (pGraphics)
+  {
+#ifdef OS_WIN
+    if (!pGraphics->OpenWindow(gHWND))
+      pGraphics=0;
+#else // Cocoa OSX
+    if (!pGraphics->OpenWindow(gHWND))
+      pGraphics=0;
+#endif
+    if (pGraphics)
+    {
+      gPluginInstance->OnGUIOpen();
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void Init()
+{
+  TryToChangeAudioDriverType(); // will init RTAudio with an API type based on gState->mAudioDriverType
+  ProbeAudioIO(); // find out what audio IO devs are available and put their IDs in the global variables gAudioInputDevs / gAudioOutputDevs
+  InitialiseMidi(); // creates RTMidiIn and RTMidiOut objects
+  ProbeMidiIO(); // find out what midi IO devs are available and put their names in the global variables gMidiInputDevs / gMidiOutputDevs
+
+  // Initialise the plugin
+  gPluginInstance = MakePlug(gMidiOut, &gState->mMidiOutChan);
+  gPluginInstance->RestorePreset(0);
+
+  ChooseMidiInput(gState->mMidiInDev);
+  ChooseMidiOutput(gState->mMidiOutDev);
+
+  TryToChangeAudio();
+}
+
+void Cleanup()
+{
+  try
+  {
+    // Stop the stream
+    gDAC->stopStream();
+  }
+  catch (RtError& e)
+  {
+    e.printMessage();
+  }
+
+  gMidiIn->cancelCallback();
+  gMidiIn->closePort();
+  gMidiOut->closePort();
+
+  if ( gDAC->isStreamOpen() ) gDAC->closeStream();
+
+  delete gPluginInstance;
+  delete gState;
+  delete gTempState;
+  delete gActiveState;
+  delete gMidiIn;
+  delete gMidiOut;
+  delete gDAC;
+  delete [] gINIPath;
+}
+
+#ifdef OS_WIN
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nShowCmd)
+{
+  // first check to make sure this is the only instance running
+  // http://www.bcbjournal.org/articles/vol3/9911/Single-instance_applications.htm
+  try
+  {
+    // Try to open the mutex.
+    HANDLE hMutex = OpenMutex(
+                      MUTEX_ALL_ACCESS, 0, BUNDLE_NAME);
+
+    // If hMutex is 0 then the mutex doesn't exist.
+    if (!hMutex)
+      hMutex = CreateMutex(0, 0, BUNDLE_NAME);
+    else
+    {
+      // This is a second instance. Bring the
+      // original instance to the top.
+      HWND hWnd = FindWindow(0, BUNDLE_NAME);
+      SetForegroundWindow(hWnd);
+
+      return 0;
+    }
+
+    gHINST=hInstance;
+
+    InitCommonControls();
+    gScrollMessage = RegisterWindowMessage("MSWHEEL_ROLLMSG");
+
+    gState = new AppState();
+    gTempState = new AppState();
+    gActiveState = new AppState();
+
+    if (SHGetFolderPathA( NULL, CSIDL_LOCAL_APPDATA, NULL, 0, gINIPath ) != S_OK)
+    {
+      DBGMSG("could not retrieve the user's application data directory!\n");
+
+      //TODO error msg?
+      return 1;
+    }
+
+    sprintf(gINIPath, "%s\\%s", gINIPath, BUNDLE_NAME); // Add the app name to the path
+
+    struct stat st;
+    if(stat(gINIPath, &st) == 0) // if directory exists
+    {
+      sprintf(gINIPath, "%s\\%s", gINIPath, "settings.ini"); // add file name to path
+
+      if(stat(gINIPath, &st) == 0) // if settings file exists read values into state
+      {
+        gState->mAudioDriverType = GetPrivateProfileInt("audio", "driver", 0, gINIPath);
+
+        GetPrivateProfileString("audio", "indev", DEFAULT_INPUT_DEV, gState->mAudioInDev, 100, gINIPath);
+        GetPrivateProfileString("audio", "outdev", DEFAULT_OUTPUT_DEV, gState->mAudioOutDev, 100, gINIPath);
+
+        //audio
+        gState->mAudioInChanL = GetPrivateProfileInt("audio", "in1", 1, gINIPath); // 1 is first audio input
+        gState->mAudioInChanR = GetPrivateProfileInt("audio", "in2", 2, gINIPath);
+        gState->mAudioOutChanL = GetPrivateProfileInt("audio", "out1", 1, gINIPath); // 1 is first audio output
+        gState->mAudioOutChanR = GetPrivateProfileInt("audio", "out2", 2, gINIPath);
+        gState->mAudioInIsMono = GetPrivateProfileInt("audio", "monoinput", 0, gINIPath);
+
+        GetPrivateProfileString("audio", "iovs", "512", gState->mAudioIOVS, 100, gINIPath);
+        GetPrivateProfileString("audio", "sigvs", "32", gState->mAudioSigVS, 100, gINIPath);
+        GetPrivateProfileString("audio", "sr", "44100", gState->mAudioSR, 100, gINIPath);
+
+        //midi
+        GetPrivateProfileString("midi", "indev", "no input", gState->mMidiInDev, 100, gINIPath);
+        GetPrivateProfileString("midi", "outdev", "no output", gState->mMidiOutDev, 100, gINIPath);
+
+        gState->mMidiInChan = GetPrivateProfileInt("midi", "inchan", 0, gINIPath); // 0 is any
+        gState->mMidiOutChan = GetPrivateProfileInt("midi", "outchan", 0, gINIPath); // 1 is first chan
+
+        UpdateINI(); // this will write over any invalid values in the file
+      }
+      else // settings file doesn't exist, so populate with default values
+      {
+        UpdateINI();
+      }
+    }
+    else
+    {
+      // folder doesn't exist - make folder and make file
+      CreateDirectory(gINIPath, NULL);
+      sprintf(gINIPath, "%s%s", gINIPath, "settings.ini"); // add file name to path
+      UpdateINI(); // will write file if doesn't exist
+    }
+
+    Init();
+
+    CreateDialog(gHINST,MAKEINTRESOURCE(IDD_DIALOG_MAIN),GetDesktopWindow(),MainDlgProc);
+
+    for(;;)
+    {
+      MSG msg= {0,};
+      int vvv = GetMessage(&msg,NULL,0,0);
+      if (!vvv)  break;
+
+      if (vvv<0)
+      {
+        Sleep(10);
+        continue;
+      }
+      if (!msg.hwnd)
+      {
+        DispatchMessage(&msg);
+        continue;
+      }
+
+      if (gHWND && IsDialogMessage(gHWND,&msg)) continue;
+
+      // default processing for other dialogs
+      HWND hWndParent=NULL;
+      HWND temphwnd = msg.hwnd;
+      do
+      {
+        if (GetClassLong(temphwnd, GCW_ATOM) == (INT)32770)
+        {
+          hWndParent=temphwnd;
+          if (!(GetWindowLong(temphwnd,GWL_STYLE)&WS_CHILD)) break; // not a child, exit
+        }
+      }
+      while (temphwnd = GetParent(temphwnd));
+
+      if (hWndParent && IsDialogMessage(hWndParent,&msg)) continue;
+
+      TranslateMessage(&msg);
+      DispatchMessage(&msg);
+
+    }
+
+    // in case gHWND didnt get destroyed -- this corresponds to SWELLAPP_DESTROY roughly
+    if (gHWND) DestroyWindow(gHWND);
+
+    Cleanup();
+
+    ReleaseMutex(hMutex);
+  }
+  catch(...)
+  {
+    //TODO proper error catching
+    DBGMSG("another instance running");
+  }
+  return 0;
+}
+#else
+
+extern HMENU SWELL_app_stocksysmenu;
+const char *homeDir;
+
+INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2)
+{
+  switch (msg)
+  {
+    case SWELLAPP_ONLOAD:
+
+      gState = new AppState();
+      gTempState = new AppState();
+      gActiveState = new AppState();
+
+      homeDir = getenv("HOME");
+      sprintf(gINIPath, "%s/Library/Application Support/%s/", homeDir, BUNDLE_NAME);
+
+      struct stat st;
+      if(stat(gINIPath, &st) == 0) // if directory exists
+      {
+        sprintf(gINIPath, "%s%s", gINIPath, "settings.ini"); // add file name to path
+
+        if(stat(gINIPath, &st) == 0) // if settings file exists read values into state
+        {
+          gState->mAudioDriverType = GetPrivateProfileInt("audio", "driver", 0, gINIPath);
+
+          GetPrivateProfileString("audio", "indev", "Built-in Input", gState->mAudioInDev, 100, gINIPath);
+          GetPrivateProfileString("audio", "outdev", "Built-in Output", gState->mAudioOutDev, 100, gINIPath);
+
+          //audio
+          gState->mAudioInChanL = GetPrivateProfileInt("audio", "in1", 1, gINIPath); // 1 is first audio input
+          gState->mAudioInChanR = GetPrivateProfileInt("audio", "in2", 2, gINIPath);
+          gState->mAudioOutChanL = GetPrivateProfileInt("audio", "out1", 1, gINIPath); // 1 is first audio output
+          gState->mAudioOutChanR = GetPrivateProfileInt("audio", "out2", 2, gINIPath);
+          gState->mAudioInIsMono = GetPrivateProfileInt("audio", "monoinput", 0, gINIPath);
+
+          GetPrivateProfileString("audio", "iovs", "512", gState->mAudioIOVS, 100, gINIPath);
+          GetPrivateProfileString("audio", "sigvs", "32", gState->mAudioSigVS, 100, gINIPath);
+          GetPrivateProfileString("audio", "sr", "44100", gState->mAudioSR, 100, gINIPath);
+
+          //midi
+          GetPrivateProfileString("midi", "indev", "no input", gState->mMidiInDev, 100, gINIPath);
+          GetPrivateProfileString("midi", "outdev", "no output", gState->mMidiOutDev, 100, gINIPath);
+
+          gState->mMidiInChan = GetPrivateProfileInt("midi", "inchan", 0, gINIPath); // 0 is any
+          gState->mMidiOutChan = GetPrivateProfileInt("midi", "outchan", 0, gINIPath); // 1 is first chan
+
+          UpdateINI(); // this will write over any invalid values in the file
+        }
+        else // settings file doesn't exist, so populate with default values
+        {
+          UpdateINI();
+        }
+
+      }
+      else   // folder doesn't exist - make folder and make file
+      {
+        // http://blog.tremend.ro/2008/10/06/create-directories-in-c-using-mkdir-with-proper-permissions/
+
+        mode_t process_mask = umask(0);
+        int result_code = mkdir(gINIPath, S_IRWXU | S_IRWXG | S_IRWXO);
+        umask(process_mask);
+
+        if(result_code) return 1;
+        else
+        {
+          sprintf(gINIPath, "%s%s", gINIPath, "settings.ini"); // add file name to path
+          UpdateINI(); // will write file if doesn't exist
+        }
+      }
+      break;
+#pragma mark loaded
+    case SWELLAPP_LOADED:
+    {
+      Init();
+
+      HMENU menu = SWELL_GetCurrentMenu();
+
+      if (menu)
+      {
+        // other windows will get the stock (bundle) menus
+        //SWELL_SetDefaultModalWindowMenu(menu);
+        //SWELL_SetDefaultWindowMenu(menu);
+
+        // work on a new menu
+        menu = SWELL_DuplicateMenu(menu);
+        HMENU src = LoadMenu(NULL,MAKEINTRESOURCE(IDR_MENU1));
+        int x;
+        for (x=0; x<GetMenuItemCount(src)-1; x++)
+        {
+          HMENU sm = GetSubMenu(src,x);
+          if (sm)
+          {
+            char str[1024];
+            MENUITEMINFO mii= {sizeof(mii),MIIM_TYPE,};
+            mii.dwTypeData=str;
+            mii.cch=sizeof(str);
+            str[0]=0;
+            GetMenuItemInfo(src,x,TRUE,&mii);
+            MENUITEMINFO mi= {sizeof(mi),MIIM_STATE|MIIM_SUBMENU|MIIM_TYPE,MFT_STRING,0,0,SWELL_DuplicateMenu(sm),NULL,NULL,0,str};
+            InsertMenuItem(menu,x+1,TRUE,&mi);
+          }
+        }
+      }
+
+      if (menu)
+      {
+        HMENU sm=GetSubMenu(menu,1);
+        DeleteMenu(sm,ID_QUIT,MF_BYCOMMAND); // remove QUIT from our file menu, since it is in the system menu on OSX
+        DeleteMenu(sm,ID_PREFERENCES,MF_BYCOMMAND); // remove PREFERENCES from the file menu, since it is in the system menu on OSX
+
+        // remove any trailing separators
+        int a= GetMenuItemCount(sm);
+        while (a > 0 && GetMenuItemID(sm,a-1)==0) DeleteMenu(sm,--a,MF_BYPOSITION);
+
+        DeleteMenu(menu,1,MF_BYPOSITION); // delete file menu
+      }
+
+      // if we want to set any default modifiers for items in the menus, we can use:
+      // SetMenuItemModifier(menu,commandID,MF_BYCOMMAND,'A',FCONTROL) etc.
+
+      HWND hwnd = CreateDialog(gHINST,MAKEINTRESOURCE(IDD_DIALOG_MAIN),NULL,MainDlgProc);
+      if (menu)
+      {
+        SetMenu(hwnd, menu); // set the menu for the dialog to our menu (on Windows that menu is set from the .rc, but on SWELL
+        SWELL_SetDefaultModalWindowMenu(menu); // other windows will get the stock (bundle) menus
+      }
+      // we need to set it manually (and obviously we've edited the menu anyway)
+    }
+
+    if(!AttachGUI()) DBGMSG("couldn't attach gui\n"); //todo error
+
+    break;
+    case SWELLAPP_ONCOMMAND:
+      // this is to catch commands coming from the system menu etc
+      if (gHWND && (parm1&0xffff)) SendMessage(gHWND,WM_COMMAND,parm1&0xffff,0);
+      break;
+#pragma mark destroy
+    case SWELLAPP_DESTROY:
+
+      if (gHWND) DestroyWindow(gHWND);
+      Cleanup();
+      break;
+    case SWELLAPP_PROCESSMESSAGE: // can hook keyboard input here
+      // parm1 = (MSG*), should we want it -- look in swell.h to see what the return values refer to
+      break;
+  }
+  return 0;
+}
+
+#endif
+
+
+#ifndef OS_WIN
+#include "swell-dlggen.h"
+
+#define SET_IDD_SCALE 1.
+#define SET_IDD_STYLE SWELL_DLG_WS_FLIPPED|SWELL_DLG_WS_NOAUTOSIZE
+
+SWELL_DEFINE_DIALOG_RESOURCE_BEGIN(IDD_DIALOG_MAIN, SET_IDD_STYLE, BUNDLE_NAME, GUI_WIDTH, GUI_HEIGHT, SET_IDD_SCALE)
+BEGIN
+//   EDITTEXT        IDC_EDIT1,59,50,145,14,ES_AUTOHSCROLL
+//   LTEXT           "Enter some text here:",IDC_STATIC,59,39,73,8
+END
+SWELL_DEFINE_DIALOG_RESOURCE_END(IDD_DIALOG_MAIN)
+
+SWELL_DEFINE_DIALOG_RESOURCE_BEGIN(IDD_DIALOG_PREF,SET_IDD_STYLE,"Preferences",320,420,SET_IDD_SCALE)
+BEGIN
+GROUPBOX        "Audio Settings", IDC_STATIC, 5, 10, 300, 230
+
+LTEXT           "Driver Type", IDC_STATIC, 20, 32, 60, 20
+COMBOBOX        IDC_COMBO_AUDIO_DRIVER, 20, 50, 150, 100, CBS_DROPDOWNLIST
+
+LTEXT           "Input Device", IDC_STATIC, 20, 75, 80, 20
+COMBOBOX        IDC_COMBO_AUDIO_IN_DEV, 20, 90, 150, 100, CBS_DROPDOWNLIST
+
+LTEXT           "Output Device", IDC_STATIC, 20, 115, 80, 20
+COMBOBOX        IDC_COMBO_AUDIO_OUT_DEV, 20, 130, 150, 100, CBS_DROPDOWNLIST
+
+LTEXT           "In 1 (L)", IDC_STATIC, 20, 155, 90, 20
+COMBOBOX        IDC_COMBO_AUDIO_IN_L, 20, 170, 46, 100, CBS_DROPDOWNLIST
+
+LTEXT           "In 2 (R)", IDC_STATIC, 75, 155, 90, 20
+COMBOBOX        IDC_COMBO_AUDIO_IN_R, 75, 170, 46, 100, CBS_DROPDOWNLIST
+
+CHECKBOX        "Mono", IDC_CB_MONO_INPUT, 125, 128, 56, 100, 0
+
+LTEXT           "Out 1 (L)", IDC_STATIC, 20, 195, 60, 20
+COMBOBOX        IDC_COMBO_AUDIO_OUT_L, 20, 210, 46, 100, CBS_DROPDOWNLIST
+
+LTEXT           "Out 2 (R)", IDC_STATIC, 75, 195, 60, 20
+COMBOBOX        IDC_COMBO_AUDIO_OUT_R, 75, 210, 46, 100, CBS_DROPDOWNLIST
+
+LTEXT           "IO Vector Size", IDC_STATIC, 200, 32, 80, 20
+COMBOBOX        IDC_COMBO_AUDIO_IOVS, 200, 50, 90, 100, CBS_DROPDOWNLIST
+
+LTEXT           "Signal Vector Size", IDC_STATIC, 200, 75, 100, 20
+COMBOBOX        IDC_COMBO_AUDIO_SIGVS, 200, 90, 90, 100, CBS_DROPDOWNLIST
+
+LTEXT           "Sampling Rate", IDC_STATIC, 200, 115, 80, 20
+COMBOBOX        IDC_COMBO_AUDIO_SR, 200, 130, 90, 100, CBS_DROPDOWNLIST
+
+PUSHBUTTON      "Audio Midi Setup...", IDC_BUTTON_ASIO, 180, 170, 110, 40
+
+GROUPBOX        "MIDI Settings", IDC_STATIC, 5, 255, 300, 120
+
+LTEXT           "Input Device", IDC_STATIC, 20, 275, 100, 20
+COMBOBOX        IDC_COMBO_MIDI_IN_DEV, 20, 293, 150, 100, CBS_DROPDOWNLIST
+
+LTEXT           "Output Device", IDC_STATIC, 20, 320, 100, 20
+COMBOBOX        IDC_COMBO_MIDI_OUT_DEV, 20, 338, 150, 100, CBS_DROPDOWNLIST
+
+LTEXT           "Input Channel", IDC_STATIC, 200, 275, 100, 20
+COMBOBOX        IDC_COMBO_MIDI_IN_CHAN, 200, 293, 90, 100, CBS_DROPDOWNLIST
+
+LTEXT           "Output Channel", IDC_STATIC, 200, 320, 100, 20
+COMBOBOX        IDC_COMBO_MIDI_OUT_CHAN, 200, 338, 90, 100, CBS_DROPDOWNLIST
+
+DEFPUSHBUTTON   "OK", IDOK, 192, 383, 50, 20
+PUSHBUTTON      "Apply", IDAPPLY, 132, 383, 50, 20
+PUSHBUTTON      "Cancel", IDCANCEL, 252, 383, 50, 20
+END
+SWELL_DEFINE_DIALOG_RESOURCE_END(IDD_DIALOG_PREF)
+
+#include "swell-menugen.h"
+
+SWELL_DEFINE_MENU_RESOURCE_BEGIN(IDR_MENU1)
+POPUP "&File"
+BEGIN
+// MENUITEM SEPARATOR
+MENUITEM "Preferences...",              ID_PREFERENCES
+MENUITEM "&Quit",                       ID_QUIT
+END
+POPUP "&Help"
+BEGIN
+MENUITEM "&About",                      ID_ABOUT
+END
+SWELL_DEFINE_MENU_RESOURCE_END(IDR_MENU1)
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app_wrapper/app_main.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,147 @@
+#ifndef _IPLUGAPP_APP_MAIN_H_
+#define _IPLUGAPP_APP_MAIN_H_
+
+#include "IPlugOSDetect.h"
+
+/*
+
+ Standalone osx/win app wrapper for iPlug, using SWELL
+ Oli Larkin 2012
+
+ Notes:
+
+ App settings are stored in a .ini file. The location is as follows:
+
+ Windows7: C:\Users\USERNAME\AppData\Local\AccessiblePeakMeter\settings.ini
+ Windows XP/Vista: C:\Documents and Settings\USERNAME\Local Settings\Application Data\AccessiblePeakMeter\settings.ini
+ OSX: /Users/USERNAME/Library/Application\ Support/AccessiblePeakMeter/settings.ini
+
+*/
+
+#ifdef OS_WIN
+  #include <windows.h>
+  #include <commctrl.h>
+
+  #define DEFAULT_INPUT_DEV "Default Device"
+  #define DEFAULT_OUTPUT_DEV "Default Device"
+
+  #define DAC_DS 0
+  #define DAC_ASIO 1
+#else if defined OS_OSX
+  #include "swell.h"
+  #define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) )
+
+  #define DEFAULT_INPUT_DEV "Built-in Input"
+  #define DEFAULT_OUTPUT_DEV "Built-in Output"
+
+  #define DAC_COREAUDIO 0
+//  #define DAC_JACK 1
+#endif
+
+#include "wdltypes.h"
+#include "RtAudio.h"
+#include "RtMidi.h"
+#include <string>
+#include <vector>
+
+#include "../AccessiblePeakMeter.h" // change this to match your iplug plugin .h file
+
+typedef unsigned short UInt16;
+
+struct AppState
+{
+  // on osx core audio 0 or jack 1
+  // on windows DS 0 or ASIO 1
+  UInt16 mAudioDriverType;
+
+  // strings
+  char mAudioInDev[100];
+  char mAudioOutDev[100];
+  char mAudioSR[100];
+  char mAudioIOVS[100];
+  char mAudioSigVS[100];
+
+  UInt16 mAudioInChanL;
+  UInt16 mAudioInChanR;
+  UInt16 mAudioOutChanL;
+  UInt16 mAudioOutChanR;
+  UInt16 mAudioInIsMono;
+
+  // strings containing the names of the midi devices
+  char mMidiInDev[100];
+  char mMidiOutDev[100];
+
+  UInt16 mMidiInChan;
+  UInt16 mMidiOutChan;
+
+  AppState():
+    mAudioDriverType(0), // DS / CoreAudio by default
+    mAudioInChanL(1),
+    mAudioInChanR(2),
+    mAudioOutChanL(1),
+    mAudioOutChanR(2),
+    mMidiInChan(0),
+    mMidiOutChan(0)
+  {
+    strcpy(mAudioInDev, DEFAULT_INPUT_DEV);
+    strcpy(mAudioOutDev, DEFAULT_OUTPUT_DEV);
+    strcpy(mAudioSR, "44100");
+    strcpy(mAudioIOVS, "512");
+    strcpy(mAudioSigVS, "32");
+
+    strcpy(mMidiInDev, "off");
+    strcpy(mMidiOutDev, "off");
+  }
+};
+
+extern WDL_DLGRET MainDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+extern WDL_DLGRET PreferencesDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+extern HINSTANCE gHINST;
+extern HWND gHWND;
+extern UINT gScrollMessage;
+extern IPlug* gPluginInstance; // The iplug plugin instance
+
+extern std::string GetAudioDeviceName(int idx);
+extern int GetAudioDeviceID(char* deviceNameToTest);
+
+extern void ProbeAudioIO();
+extern bool InitialiseAudio(unsigned int inId,
+                            unsigned int outId,
+                            unsigned int sr,
+                            unsigned int iovs,
+                            unsigned int chnls,
+                            unsigned int inChanL,
+                            unsigned int outChanL
+                           );
+
+extern bool AudioSettingsInStateAreEqual(AppState* os, AppState* ns);
+extern bool MIDISettingsInStateAreEqual(AppState* os, AppState* ns);
+
+extern bool TryToChangeAudioDriverType();
+extern bool TryToChangeAudio();
+extern bool ChooseMidiInput(const char* pPortName);
+extern bool ChooseMidiOutput(const char* pPortName);
+
+extern bool AttachGUI();
+
+extern RtAudio* gDAC;
+extern RtMidiIn *gMidiIn;
+extern RtMidiOut *gMidiOut;
+
+extern AppState *gState;
+extern AppState *gTempState; // The state is copied here when the pref dialog is opened, and restored if cancel is pressed
+extern AppState *gActiveState; // When the audio driver is started the current state is copied here so that if OK is pressed after APPLY nothing is changed
+
+extern unsigned int gSigVS;
+extern unsigned int gBufIndex; // index for signal vector, loops from 0 to gSigVS
+
+extern char *gINIPath; // path of ini file
+extern void UpdateINI();
+
+extern std::vector<unsigned int> gAudioInputDevs;
+extern std::vector<unsigned int> gAudioOutputDevs;
+extern std::vector<std::string> gMIDIInputDevNames;
+extern std::vector<std::string> gMIDIOutputDevNames;
+
+#endif //_IPLUGAPP_APP_MAIN_H_
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app_wrapper/app_resource.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,42 @@
+// RESOURCE IDS FOR STANDALONE APP
+
+#ifndef IDC_STATIC
+#define IDC_STATIC (-1)
+#endif
+
+#define IDD_DIALOG_MAIN             40001
+#define IDD_DIALOG_PREF             40002
+#define IDI_ICON1                   40003
+#define IDR_MENU1                   40004
+
+#define ID_ABOUT                    40005
+#define ID_PREFERENCES              40006
+#define ID_QUIT                     40007
+
+#define IDC_COMBO_AUDIO_DRIVER      40008
+#define IDC_COMBO_AUDIO_IN_DEV      40009
+#define IDC_COMBO_AUDIO_OUT_DEV     40010
+#define IDC_COMBO_AUDIO_IOVS        40011
+#define IDC_COMBO_AUDIO_SIGVS       40012
+#define IDC_COMBO_AUDIO_SR          40013
+#define IDC_COMBO_AUDIO_IN_L        40014
+#define IDC_COMBO_AUDIO_IN_R        40015
+#define IDC_COMBO_AUDIO_OUT_R       40016
+#define IDC_COMBO_AUDIO_OUT_L       40017
+#define IDC_COMBO_MIDI_IN_DEV       40018
+#define IDC_COMBO_MIDI_OUT_DEV      40019
+#define IDC_COMBO_MIDI_IN_CHAN      40020
+#define IDC_COMBO_MIDI_OUT_CHAN     40021
+#define IDC_BUTTON_ASIO             40022
+#define IDC_CB_MONO_INPUT           40023
+
+#define IDAPPLY                     40024
+
+// some options for the app
+
+#define ENABLE_SYSEX 0
+#define ENABLE_MIDICLOCK 0
+#define ENABLE_ACTIVE_SENSING 0
+#define NUM_CHANNELS 2
+#define N_VECTOR_WAIT 50
+#define APP_MULT 0.25
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app_wrapper/main.mm	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,6 @@
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, char *argv[])
+{
+  return NSApplicationMain(argc,  (const char **) argv);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resource.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,99 @@
+//
+// resource.h 
+//
+// Author: Fiore Martin 
+// Started from IPlugMultiTargets example in WDL-OL, by Oli Larkin - https://github.com/olilarkin/wdl-ol
+//
+// Licensed under the Cockos WDL License, see README.txt
+//
+
+#define PLUG_MFR "QueenMaryUniversityOfLondon"
+#define PLUG_NAME "AccessiblePeakMeter2S"
+
+#define PLUG_CLASS_NAME AccessiblePeakMeter
+
+#define BUNDLE_MFR "QueenMaryUniversityOfLondon"
+#define BUNDLE_NAME "AccessiblePeakMeter2S"
+
+#define PLUG_ENTRY AccessiblePeakMeter_Entry
+#define PLUG_VIEW_ENTRY AccessiblePeakMeter_ViewEntry
+
+#define PLUG_ENTRY_STR "AccessiblePeakMeter_Entry"
+#define PLUG_VIEW_ENTRY_STR "AccessiblePeakMeter_ViewEntry"
+
+#define VIEW_CLASS AccessiblePeakMeter_View
+#define VIEW_CLASS_STR "AccessiblePeakMeter_View"
+
+// Format        0xMAJR.MN.BG - in HEX! so version 10.1.5 would be 0x000A0105
+#define PLUG_VER 0x00010000
+#define VST3_VER_STR "1.0.0"
+
+// http://service.steinberg.de/databases/plugin.nsf/plugIn?openForm
+// 4 chars, single quotes. At least one capital letter
+#define PLUG_UNIQUE_ID 'f5sm'
+// make sure this is not the same as BUNDLE_MFR
+#define PLUG_MFR_ID 'Qmul'
+
+// ProTools stuff
+#if (defined(AAX_API) || defined(RTAS_API)) && !defined(_PIDS_)
+  #define _PIDS_
+  const int PLUG_TYPE_IDS[2] = {'MAN1', 'MAN2'};
+#endif
+#define PLUG_MFR_PT "QueenMaryUniversityOfLondon\nQueenMaryUniversityOfLondon\nQmul"
+#define PLUG_NAME_PT "AccessiblePeakMeter\nAccessiblePeakMeter"
+#define PLUG_TYPE_PT "Effect"
+#define PLUG_DOES_AUDIOSUITE 0
+
+/* PLUG_TYPE_PT can be "None", "EQ", "Dynamics", "PitchShift", "Reverb", "Delay", "Modulation", 
+"Harmonic" "NoiseReduction" "Dither" "SoundField" "Effect" 
+instrument determined by PLUG _IS _INST
+*/
+
+#define PLUG_CHANNEL_IO "1-1 2-2"
+
+#define PLUG_LATENCY 0
+#define PLUG_IS_INST 0
+
+// if this is 0 RTAS can't get tempo info
+#define PLUG_DOES_MIDI 0
+
+#define PLUG_DOES_STATE_CHUNKS 0
+
+// Unique IDs for each image resource.
+
+#define BG_ID         100
+#define KNOB_ID       101
+#define FADER_ID      102
+#define SWITCH_ID     103
+
+
+// Image resource locations for this plug.
+#define KNOB_FN       "resources/img/knob.png"
+#define BG_FN         "resources/img/bg.png"
+#define FADER_FN      "resources/img/fader.png"
+#define SWITCH_FN      "resources/img/switch.png"
+
+// GUI default dimensions
+#define GUI_WIDTH   315
+#define GUI_HEIGHT  249
+
+// on MSVC, you must define SA_API in the resource editor preprocessor macros as well as the c++ ones
+#ifdef SA_API
+#ifndef OS_IOS
+#include "app_wrapper/app_resource.h"
+#endif
+#endif
+
+// vst3 stuff
+#define MFR_URL ""
+#define MFR_EMAIL ""
+#define EFFECT_TYPE_VST3 "Fx"
+
+/* "Fx|Analyzer"", "Fx|Delay", "Fx|Distortion", "Fx|Dynamics", "Fx|EQ", "Fx|Filter",
+"Fx", "Fx|Instrument", "Fx|InstrumentExternal", "Fx|Spatial", "Fx|Generator",
+"Fx|Mastering", "Fx|Modulation", "Fx|PitchShift", "Fx|Restoration", "Fx|Reverb",
+"Fx|Surround", "Fx|Tools", "Instrument", "Instrument|Drum", "Instrument|Sampler",
+"Instrument|Synth", "Instrument|Synth|Sampler", "Instrument|External", "Spatial",
+"Spatial|Fx", "OnlyRT", "OnlyOfflineProcess", "Mono", "Stereo",
+"Surround"
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/AccessiblePeakMeter-AAX-Info.plist	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>${BINARY_NAME}</string>
+	<key>CFBundleGetInfoString</key>
+	<string>1.0.0, Copyright QueenMaryUniversityOfLondon, 2012</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.QueenMaryUniversityOfLondon.aax.${BINARY_NAME}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${BINARY_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>TDMw</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0.0</string>
+	<key>CFBundleSignature</key>
+	<string>PTul</string>
+	<key>CFBundleVersion</key>
+	<string>1.0.0</string>
+	<key>LSMultipleInstancesProhibited</key>
+	<string>true</string>
+	<key>LSPrefersCarbon</key>
+	<false/>
+	<key>NSAppleScriptEnabled</key>
+	<string>No</string>
+</dict>
+</plist>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/AccessiblePeakMeter-AU-Info.plist	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>${BINARY_NAME}</string>
+	<key>CFBundleGetInfoString</key>
+	<string>1.0.0, Copyright QueenMaryUniversityOfLondon, 2012</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.QueenMaryUniversityOfLondon.audiounit.${BINARY_NAME}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${BINARY_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0.0</string>
+	<key>CFBundleSignature</key>
+	<string>Acme</string>
+	<key>CFBundleVersion</key>
+	<string>1.0.0</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>10.5.0</string>
+	<key>NSPrincipalClass</key>
+	<string>AccessiblePeakMeter_View</string>
+</dict>
+</plist>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/AccessiblePeakMeter-IOSAPP-Info.plist	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDisplayName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleGetInfoString</key>
+	<string>1.0.0, Copyright QueenMaryUniversityOfLondon, 2011</string>
+	<key>CFBundleIconFile</key>
+	<string>AccessiblePeakMeter-icon57x57.png</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.QueenMaryUniversityOfLondon.${PRODUCT_NAME:rfc1034identifier}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0.0</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>NSMainNibFile</key>
+	<string>MainWindow</string>
+</dict>
+</plist>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/AccessiblePeakMeter-OSXAPP-Info.plist	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>${BINARY_NAME}</string>
+	<key>CFBundleGetInfoString</key>
+	<string>1.0.0, Copyright QueenMaryUniversityOfLondon, 2012</string>
+	<key>CFBundleIconFile</key>
+	<string>${BINARY_NAME}.icns</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.QueenMaryUniversityOfLondon.standalone.${BINARY_NAME}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${BINARY_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0.0</string>
+	<key>CFBundleSignature</key>
+	<string>Acme</string>
+	<key>CFBundleVersion</key>
+	<string>1.0.0</string>
+	<key>LSApplicationCategoryType</key>
+	<string>public.app-category.music</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>10.5.0</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>SWELLApplication</string>
+</dict>
+</plist>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/AccessiblePeakMeter-Pages.xml	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,143 @@
+<?xml version='1.0' encoding='US-ASCII' standalone='yes'?>
+<PageTables vers='6.4.0.91'>
+	<PageTableLayouts>
+		<Plugin manID='Acme' prodID='Ipef' plugID='Ipef'>
+			<Desc>AccessiblePeakMeter by QueenMaryUniversityOfLondon.</Desc>
+			<Layout>PageTable 1</Layout>
+		</Plugin><!--manID='Acme' prodID='Ipef' plugID='Ipef'-->
+		<PTLayout name='PageTable 1'>
+			<PageTable type='BkCS' pgsz='12'>
+				<Page num='1'>
+					<ID>1</ID>
+					<ID> </ID>
+					<ID> </ID>
+					<ID> </ID>
+					<ID> </ID>
+					<ID> </ID>
+					<ID>MasterBypass</ID>
+				</Page><!--num='1'-->
+			</PageTable><!--type='BkCS' pgsz='12'-->
+			<PageTable type='BkSF' pgsz='16'>
+				<Page num='1'>
+					<ID>1</ID>
+					<ID> </ID>
+					<ID> </ID>
+					<ID> </ID>
+					<ID> </ID>
+					<ID> </ID>
+					<ID> </ID>
+					<ID> </ID>
+					<ID>MasterBypass</ID>
+				</Page><!--num='1'-->
+			</PageTable><!--type='BkSF' pgsz='16'-->
+			<PageTable type='FrTL' pgsz='24'>
+				<Page num='1'>
+					<ID>MasterBypass</ID>
+					<ID>1</ID>
+				</Page><!--num='1'-->
+				<FirstPg cat='0'>1</FirstPg>
+				<FirstPg cat='1'>1</FirstPg>
+				<FirstPg cat='2'>1</FirstPg>
+				<FirstPg cat='4'>1</FirstPg>
+				<FirstPg cat='8'>1</FirstPg>
+				<FirstPg cat='16'>1</FirstPg>
+				<FirstPg cat='32'>1</FirstPg>
+				<FirstPg cat='64'>1</FirstPg>
+				<FirstPg cat='128'>1</FirstPg>
+				<FirstPg cat='256'>1</FirstPg>
+				<FirstPg cat='512'>1</FirstPg>
+				<FirstPg cat='1024'>1</FirstPg>
+				<FirstPg cat='2048'>1</FirstPg>
+			</PageTable><!--type='FrTL' pgsz='24'-->
+			<PageTable type='HgTL' pgsz='8'>
+				<Page num='1'>
+					<ID> </ID>
+					<ID>1</ID>
+					<ID>MasterBypass</ID>
+				</Page><!--num='1'-->
+				<FirstPg cat='0'>1</FirstPg>
+				<FirstPg cat='1'>1</FirstPg>
+				<FirstPg cat='2'>1</FirstPg>
+				<FirstPg cat='4'>1</FirstPg>
+				<FirstPg cat='8'>1</FirstPg>
+				<FirstPg cat='16'>1</FirstPg>
+				<FirstPg cat='32'>1</FirstPg>
+				<FirstPg cat='64'>1</FirstPg>
+				<FirstPg cat='128'>1</FirstPg>
+				<FirstPg cat='256'>1</FirstPg>
+				<FirstPg cat='512'>1</FirstPg>
+				<FirstPg cat='1024'>1</FirstPg>
+				<FirstPg cat='2048'>1</FirstPg>
+			</PageTable><!--type='HgTL' pgsz='8'-->
+			<PageTable type='MkTL' pgsz='8'>
+				<Page num='1'>
+					<ID> </ID>
+					<ID>1</ID>
+					<ID>MasterBypass</ID>
+				</Page><!--num='1'-->
+				<FirstPg cat='0'>1</FirstPg>
+				<FirstPg cat='1'>1</FirstPg>
+				<FirstPg cat='2'>1</FirstPg>
+				<FirstPg cat='4'>1</FirstPg>
+				<FirstPg cat='8'>1</FirstPg>
+				<FirstPg cat='16'>1</FirstPg>
+				<FirstPg cat='32'>1</FirstPg>
+				<FirstPg cat='64'>1</FirstPg>
+				<FirstPg cat='128'>1</FirstPg>
+				<FirstPg cat='256'>1</FirstPg>
+				<FirstPg cat='512'>1</FirstPg>
+				<FirstPg cat='1024'>1</FirstPg>
+				<FirstPg cat='2048'>1</FirstPg>
+			</PageTable><!--type='MkTL' pgsz='8'-->
+			<PageTable type='PcTL' pgsz='16'>
+				<Page num='1'>
+					<ID>MasterBypass</ID>
+					<ID>1</ID>
+				</Page><!--num='1'-->
+				<FirstPg cat='0'>1</FirstPg>
+				<FirstPg cat='1'>1</FirstPg>
+				<FirstPg cat='2'>1</FirstPg>
+				<FirstPg cat='4'>1</FirstPg>
+				<FirstPg cat='8'>1</FirstPg>
+				<FirstPg cat='16'>1</FirstPg>
+				<FirstPg cat='32'>1</FirstPg>
+				<FirstPg cat='64'>1</FirstPg>
+				<FirstPg cat='128'>1</FirstPg>
+				<FirstPg cat='256'>1</FirstPg>
+				<FirstPg cat='512'>1</FirstPg>
+				<FirstPg cat='1024'>1</FirstPg>
+				<FirstPg cat='2048'>1</FirstPg>
+			</PageTable><!--type='PcTL' pgsz='16'-->
+			<PageTable type='PgTL' pgsz='1'>
+				<Page num='1'>
+					<ID>MasterBypass</ID>
+				</Page><!--num='1'-->
+				<Page num='2'>
+					<ID>1</ID>
+				</Page><!--num='2'-->
+			</PageTable><!--type='PgTL' pgsz='1'-->
+		</PTLayout><!--name='PageTable 1'-->
+	</PageTableLayouts>
+	<ControlNamesVariations>
+		<Ctrl ID='MasterBypass'>
+			<name typ='PgTL' sz='1'>Ma</name>
+			<name typ='PgTL' sz='3'>Byp</name>
+			<name typ='PgTL' sz='4'>MByp</name>
+			<name typ='PgTL' sz='8'>Mstr Byp</name>
+		</Ctrl><!--ID='MasterBypass'-->
+	</ControlNamesVariations>
+	<Editor vers='1.3.7.1'>
+		<PluginList>
+			<TDM>
+			</TDM>
+			<RTAS>
+				<PluginID manID='Acme' prodID='Ipef' plugID='Ipef'>
+					<MenuStr>RTAS: AccessiblePeakMeter</MenuStr>
+				</PluginID><!--manID='Acme' prodID='Ipef' plugID='Ipef'-->
+			</RTAS>
+		</PluginList>
+		<DiscCtrls>
+			<CtrlID>MasterBypass</CtrlID>
+		</DiscCtrls>
+	</Editor><!--vers='1.3.7.1'-->
+</PageTables><!--vers='6.4.0.91'-->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/AccessiblePeakMeter-RTAS-Info.plist	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>${BINARY_NAME}</string>
+	<key>CFBundleGetInfoString</key>
+	<string>1.0.0, Copyright QueenMaryUniversityOfLondon, 2012</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.QueenMaryUniversityOfLondon.rtas.${BINARY_NAME}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${BINARY_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>TDMw</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0.0</string>
+	<key>CFBundleSignature</key>
+	<string>PTul</string>
+	<key>CFBundleVersion</key>
+	<string>1.0.0</string>
+	<key>LSMultipleInstancesProhibited</key>
+	<string>true</string>
+	<key>LSPrefersCarbon</key>
+	<true/>
+	<key>NSAppleScriptEnabled</key>
+	<string>No</string>
+</dict>
+</plist>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/AccessiblePeakMeter-VST2-Info.plist	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>${BINARY_NAME}</string>
+	<key>CFBundleGetInfoString</key>
+	<string>1.0.0, Copyright QueenMaryUniversityOfLondon, 2012</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.QueenMaryUniversityOfLondon.vst.${BINARY_NAME}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${BINARY_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0.0</string>
+	<key>CFBundleSignature</key>
+	<string>Acme</string>
+	<key>CFBundleVersion</key>
+	<string>1.0.0</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>10.5.0</string>
+</dict>
+</plist>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/AccessiblePeakMeter-VST3-Info.plist	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>${BINARY_NAME}</string>
+	<key>CFBundleGetInfoString</key>
+	<string>1.0.0, Copyright QueenMaryUniversityOfLondon, 2012</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.QueenMaryUniversityOfLondon.vst3.${BINARY_NAME}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${BINARY_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0.0</string>
+	<key>CFBundleSignature</key>
+	<string>Acme</string>
+	<key>CFBundleVersion</key>
+	<string>1.0.0</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>10.5.0</string>
+</dict>
+</plist>
Binary file resources/AccessiblePeakMeter-icon57x57.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/AccessiblePeakMeter.entitlements	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>com.apple.security.app-sandbox</key>
+	<true/>
+	<key>com.apple.security.device.microphone</key>
+	<true/>
+	<key>com.apple.security.device.usb</key>
+	<true/>
+	<key>com.apple.security.device.firewire</key>
+	<true/>
+	<key>com.apple.security.files.user-selected.read-write</key>
+	<true/>
+</dict>
+</plist>
Binary file resources/AccessiblePeakMeter.icns has changed
Binary file resources/English.lproj/InfoPlist.strings has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/English.lproj/MainMenu.xib	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,1046 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
+	<data>
+		<int key="IBDocument.SystemTarget">1050</int>
+		<string key="IBDocument.SystemVersion">10K549</string>
+		<string key="IBDocument.InterfaceBuilderVersion">851</string>
+		<string key="IBDocument.AppKitVersion">1038.36</string>
+		<string key="IBDocument.HIToolboxVersion">461.00</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
+			<string key="NS.object.0">851</string>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<integer value="29"/>
+		</object>
+		<object class="NSArray" key="IBDocument.PluginDependencies">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+		</object>
+		<object class="NSMutableDictionary" key="IBDocument.Metadata">
+			<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+			<integer value="1" key="NS.object.0"/>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="NSCustomObject" id="1021">
+				<string key="NSClassName">NSApplication</string>
+			</object>
+			<object class="NSCustomObject" id="1014">
+				<string key="NSClassName">FirstResponder</string>
+			</object>
+			<object class="NSCustomObject" id="1050">
+				<string key="NSClassName">SWELLApplication</string>
+			</object>
+			<object class="NSMenu" id="649796088">
+				<string key="NSTitle">AMainMenu</string>
+				<object class="NSMutableArray" key="NSMenuItems">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<object class="NSMenuItem" id="694149608">
+						<reference key="NSMenu" ref="649796088"/>
+						<string key="NSTitle">AccessiblePeakMeter</string>
+						<string key="NSKeyEquiv"/>
+						<int key="NSKeyEquivModMask">1048576</int>
+						<int key="NSMnemonicLoc">2147483647</int>
+						<object class="NSCustomResource" key="NSOnImage" id="35465992">
+							<string key="NSClassName">NSImage</string>
+							<string key="NSResourceName">NSMenuCheckmark</string>
+						</object>
+						<object class="NSCustomResource" key="NSMixedImage" id="502551668">
+							<string key="NSClassName">NSImage</string>
+							<string key="NSResourceName">NSMenuMixedState</string>
+						</object>
+						<string key="NSAction">submenuAction:</string>
+						<object class="NSMenu" key="NSSubmenu" id="110575045">
+							<string key="NSTitle">AccessiblePeakMeter</string>
+							<object class="NSMutableArray" key="NSMenuItems">
+								<bool key="EncodedWithXMLCoder">YES</bool>
+								<object class="NSMenuItem" id="238522557">
+									<reference key="NSMenu" ref="110575045"/>
+									<string key="NSTitle">About AccessiblePeakMeter</string>
+									<string key="NSKeyEquiv"/>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+									<int key="NSTag">40005</int>
+								</object>
+								<object class="NSMenuItem" id="304266470">
+									<reference key="NSMenu" ref="110575045"/>
+									<bool key="NSIsDisabled">YES</bool>
+									<bool key="NSIsSeparator">YES</bool>
+									<string key="NSTitle"/>
+									<string key="NSKeyEquiv"/>
+									<int key="NSKeyEquivModMask">1048576</int>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+								</object>
+								<object class="NSMenuItem" id="609285721">
+									<reference key="NSMenu" ref="110575045"/>
+									<string key="NSTitle">Preferences…</string>
+									<string key="NSKeyEquiv">,</string>
+									<int key="NSKeyEquivModMask">1048576</int>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+									<int key="NSTag">40006</int>
+								</object>
+								<object class="NSMenuItem" id="481834944">
+									<reference key="NSMenu" ref="110575045"/>
+									<bool key="NSIsDisabled">YES</bool>
+									<bool key="NSIsSeparator">YES</bool>
+									<string key="NSTitle"/>
+									<string key="NSKeyEquiv"/>
+									<int key="NSKeyEquivModMask">1048576</int>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+								</object>
+								<object class="NSMenuItem" id="1046388886">
+									<reference key="NSMenu" ref="110575045"/>
+									<string key="NSTitle">Services</string>
+									<string key="NSKeyEquiv"/>
+									<int key="NSKeyEquivModMask">1048576</int>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+									<string key="NSAction">submenuAction:</string>
+									<object class="NSMenu" key="NSSubmenu" id="752062318">
+										<string key="NSTitle">Services</string>
+										<object class="NSMutableArray" key="NSMenuItems">
+											<bool key="EncodedWithXMLCoder">YES</bool>
+										</object>
+										<string key="NSName">_NSServicesMenu</string>
+									</object>
+								</object>
+								<object class="NSMenuItem" id="646227648">
+									<reference key="NSMenu" ref="110575045"/>
+									<bool key="NSIsDisabled">YES</bool>
+									<bool key="NSIsSeparator">YES</bool>
+									<string key="NSTitle"/>
+									<string key="NSKeyEquiv"/>
+									<int key="NSKeyEquivModMask">1048576</int>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+								</object>
+								<object class="NSMenuItem" id="755159360">
+									<reference key="NSMenu" ref="110575045"/>
+									<string key="NSTitle">Hide AccessiblePeakMeter</string>
+									<string key="NSKeyEquiv">h</string>
+									<int key="NSKeyEquivModMask">1048576</int>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+								</object>
+								<object class="NSMenuItem" id="342932134">
+									<reference key="NSMenu" ref="110575045"/>
+									<string key="NSTitle">Hide Others</string>
+									<string key="NSKeyEquiv">h</string>
+									<int key="NSKeyEquivModMask">1572864</int>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+								</object>
+								<object class="NSMenuItem" id="908899353">
+									<reference key="NSMenu" ref="110575045"/>
+									<string key="NSTitle">Show All</string>
+									<string key="NSKeyEquiv"/>
+									<int key="NSKeyEquivModMask">1048576</int>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+								</object>
+								<object class="NSMenuItem" id="1056857174">
+									<reference key="NSMenu" ref="110575045"/>
+									<bool key="NSIsDisabled">YES</bool>
+									<bool key="NSIsSeparator">YES</bool>
+									<string key="NSTitle"/>
+									<string key="NSKeyEquiv"/>
+									<int key="NSKeyEquivModMask">1048576</int>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+								</object>
+								<object class="NSMenuItem" id="632727374">
+									<reference key="NSMenu" ref="110575045"/>
+									<string key="NSTitle">Quit AccessiblePeakMeter</string>
+									<string key="NSKeyEquiv">q</string>
+									<int key="NSKeyEquivModMask">1048576</int>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+									<int key="NSTag">40007</int>
+								</object>
+							</object>
+							<string key="NSName">_NSAppleMenu</string>
+						</object>
+					</object>
+					<object class="NSMenuItem" id="914547905">
+						<reference key="NSMenu" ref="649796088"/>
+						<string key="NSTitle">Window</string>
+						<string key="NSKeyEquiv"/>
+						<int key="NSMnemonicLoc">2147483647</int>
+						<reference key="NSOnImage" ref="35465992"/>
+						<reference key="NSMixedImage" ref="502551668"/>
+						<string key="NSAction">submenuAction:</string>
+						<object class="NSMenu" key="NSSubmenu" id="399816170">
+							<string key="NSTitle">Window</string>
+							<object class="NSMutableArray" key="NSMenuItems">
+								<bool key="EncodedWithXMLCoder">YES</bool>
+								<object class="NSMenuItem" id="868333253">
+									<reference key="NSMenu" ref="399816170"/>
+									<string key="NSTitle">Minimize</string>
+									<string key="NSKeyEquiv">m</string>
+									<int key="NSKeyEquivModMask">1048576</int>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+								</object>
+								<object class="NSMenuItem" id="500286786">
+									<reference key="NSMenu" ref="399816170"/>
+									<string key="NSTitle">Zoom</string>
+									<string key="NSKeyEquiv"/>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+								</object>
+								<object class="NSMenuItem" id="420554045">
+									<reference key="NSMenu" ref="399816170"/>
+									<bool key="NSIsDisabled">YES</bool>
+									<bool key="NSIsSeparator">YES</bool>
+									<string key="NSTitle"/>
+									<string key="NSKeyEquiv"/>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+								</object>
+								<object class="NSMenuItem" id="165667221">
+									<reference key="NSMenu" ref="399816170"/>
+									<string key="NSTitle">Bring All to Front</string>
+									<string key="NSKeyEquiv"/>
+									<int key="NSMnemonicLoc">2147483647</int>
+									<reference key="NSOnImage" ref="35465992"/>
+									<reference key="NSMixedImage" ref="502551668"/>
+								</object>
+							</object>
+							<string key="NSName">_NSWindowsMenu</string>
+						</object>
+					</object>
+				</object>
+				<string key="NSName">_NSMainMenu</string>
+			</object>
+			<object class="NSCustomObject" id="755631768">
+				<string key="NSClassName">NSFontManager</string>
+			</object>
+			<object class="NSCustomObject" id="660404974">
+				<string key="NSClassName">SWELLAppController</string>
+			</object>
+		</object>
+		<object class="IBObjectContainer" key="IBDocument.Objects">
+			<object class="NSMutableArray" key="connectionRecords">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">hide:</string>
+						<reference key="source" ref="1014"/>
+						<reference key="destination" ref="755159360"/>
+					</object>
+					<int key="connectionID">367</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">hideOtherApplications:</string>
+						<reference key="source" ref="1014"/>
+						<reference key="destination" ref="342932134"/>
+					</object>
+					<int key="connectionID">368</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">unhideAllApplications:</string>
+						<reference key="source" ref="1014"/>
+						<reference key="destination" ref="908899353"/>
+					</object>
+					<int key="connectionID">370</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">terminate:</string>
+						<reference key="source" ref="1050"/>
+						<reference key="destination" ref="632727374"/>
+					</object>
+					<int key="connectionID">449</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">onSysMenuCommand:</string>
+						<reference key="source" ref="660404974"/>
+						<reference key="destination" ref="238522557"/>
+					</object>
+					<int key="connectionID">451</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">performMiniaturize:</string>
+						<reference key="source" ref="1014"/>
+						<reference key="destination" ref="868333253"/>
+					</object>
+					<int key="connectionID">458</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">arrangeInFront:</string>
+						<reference key="source" ref="1014"/>
+						<reference key="destination" ref="165667221"/>
+					</object>
+					<int key="connectionID">459</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBActionConnection" key="connection">
+						<string key="label">performZoom:</string>
+						<reference key="source" ref="1014"/>
+						<reference key="destination" ref="500286786"/>
+					</object>
+					<int key="connectionID">460</int>
+				</object>
+			</object>
+			<object class="IBMutableOrderedSet" key="objectRecords">
+				<object class="NSArray" key="orderedObjects">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<object class="IBObjectRecord">
+						<int key="objectID">0</int>
+						<object class="NSArray" key="object" id="0">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+						</object>
+						<reference key="children" ref="1048"/>
+						<nil key="parent"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-2</int>
+						<reference key="object" ref="1021"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">File's Owner</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-1</int>
+						<reference key="object" ref="1014"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">First Responder</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-3</int>
+						<reference key="object" ref="1050"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">Application</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">29</int>
+						<reference key="object" ref="649796088"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="694149608"/>
+							<reference ref="914547905"/>
+						</object>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">MainMenu</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">56</int>
+						<reference key="object" ref="694149608"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="110575045"/>
+						</object>
+						<reference key="parent" ref="649796088"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">57</int>
+						<reference key="object" ref="110575045"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="238522557"/>
+							<reference ref="755159360"/>
+							<reference ref="908899353"/>
+							<reference ref="632727374"/>
+							<reference ref="646227648"/>
+							<reference ref="609285721"/>
+							<reference ref="481834944"/>
+							<reference ref="304266470"/>
+							<reference ref="1046388886"/>
+							<reference ref="1056857174"/>
+							<reference ref="342932134"/>
+						</object>
+						<reference key="parent" ref="694149608"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">58</int>
+						<reference key="object" ref="238522557"/>
+						<reference key="parent" ref="110575045"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">134</int>
+						<reference key="object" ref="755159360"/>
+						<reference key="parent" ref="110575045"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">150</int>
+						<reference key="object" ref="908899353"/>
+						<reference key="parent" ref="110575045"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">136</int>
+						<reference key="object" ref="632727374"/>
+						<reference key="parent" ref="110575045"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">144</int>
+						<reference key="object" ref="646227648"/>
+						<reference key="parent" ref="110575045"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">129</int>
+						<reference key="object" ref="609285721"/>
+						<reference key="parent" ref="110575045"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">143</int>
+						<reference key="object" ref="481834944"/>
+						<reference key="parent" ref="110575045"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">236</int>
+						<reference key="object" ref="304266470"/>
+						<reference key="parent" ref="110575045"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">131</int>
+						<reference key="object" ref="1046388886"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="752062318"/>
+						</object>
+						<reference key="parent" ref="110575045"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">149</int>
+						<reference key="object" ref="1056857174"/>
+						<reference key="parent" ref="110575045"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">145</int>
+						<reference key="object" ref="342932134"/>
+						<reference key="parent" ref="110575045"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">130</int>
+						<reference key="object" ref="752062318"/>
+						<reference key="parent" ref="1046388886"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">420</int>
+						<reference key="object" ref="755631768"/>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">450</int>
+						<reference key="object" ref="660404974"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">Controller</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">452</int>
+						<reference key="object" ref="914547905"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="399816170"/>
+						</object>
+						<reference key="parent" ref="649796088"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">453</int>
+						<reference key="object" ref="399816170"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="165667221"/>
+							<reference ref="420554045"/>
+							<reference ref="500286786"/>
+							<reference ref="868333253"/>
+						</object>
+						<reference key="parent" ref="914547905"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">457</int>
+						<reference key="object" ref="165667221"/>
+						<reference key="parent" ref="399816170"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">456</int>
+						<reference key="object" ref="420554045"/>
+						<reference key="parent" ref="399816170"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">455</int>
+						<reference key="object" ref="500286786"/>
+						<reference key="parent" ref="399816170"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">454</int>
+						<reference key="object" ref="868333253"/>
+						<reference key="parent" ref="399816170"/>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="flattenedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="NSArray" key="dict.sortedKeys">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>-3.IBPluginDependency</string>
+					<string>129.IBPluginDependency</string>
+					<string>129.ImportedFromIB2</string>
+					<string>130.IBEditorWindowLastContentRect</string>
+					<string>130.IBPluginDependency</string>
+					<string>130.ImportedFromIB2</string>
+					<string>130.editorWindowContentRectSynchronizationRect</string>
+					<string>131.IBPluginDependency</string>
+					<string>131.ImportedFromIB2</string>
+					<string>134.IBPluginDependency</string>
+					<string>134.ImportedFromIB2</string>
+					<string>136.IBPluginDependency</string>
+					<string>136.ImportedFromIB2</string>
+					<string>143.IBPluginDependency</string>
+					<string>143.ImportedFromIB2</string>
+					<string>144.IBPluginDependency</string>
+					<string>144.ImportedFromIB2</string>
+					<string>145.IBPluginDependency</string>
+					<string>145.ImportedFromIB2</string>
+					<string>149.IBPluginDependency</string>
+					<string>149.ImportedFromIB2</string>
+					<string>150.IBPluginDependency</string>
+					<string>150.ImportedFromIB2</string>
+					<string>236.IBPluginDependency</string>
+					<string>236.ImportedFromIB2</string>
+					<string>29.IBEditorWindowLastContentRect</string>
+					<string>29.IBPluginDependency</string>
+					<string>29.ImportedFromIB2</string>
+					<string>29.WindowOrigin</string>
+					<string>29.editorWindowContentRectSynchronizationRect</string>
+					<string>452.IBPluginDependency</string>
+					<string>453.IBEditorWindowLastContentRect</string>
+					<string>453.IBPluginDependency</string>
+					<string>454.IBPluginDependency</string>
+					<string>455.IBPluginDependency</string>
+					<string>456.IBPluginDependency</string>
+					<string>457.IBPluginDependency</string>
+					<string>56.IBPluginDependency</string>
+					<string>56.ImportedFromIB2</string>
+					<string>57.IBEditorWindowLastContentRect</string>
+					<string>57.IBPluginDependency</string>
+					<string>57.ImportedFromIB2</string>
+					<string>57.editorWindowContentRectSynchronizationRect</string>
+					<string>58.IBPluginDependency</string>
+					<string>58.ImportedFromIB2</string>
+				</object>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>{{490, 219}, {64, 6}}</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>{{436, 809}, {64, 6}}</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>{{239, 638}, {190, 20}}</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>{74, 862}</string>
+					<string>{{6, 978}, {478, 20}}</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>{{398, 564}, {194, 73}}</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>{{251, 455}, {207, 183}}</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+					<string>{{23, 794}, {245, 183}}</string>
+					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+					<integer value="1"/>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="unlocalizedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="activeLocalization"/>
+			<object class="NSMutableDictionary" key="localizations">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="sourceID"/>
+			<int key="maxID">485</int>
+		</object>
+		<object class="IBClassDescriber" key="IBDocument.Classes">
+			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">SWELLAppController</string>
+					<string key="superclassName">NSObject</string>
+					<object class="NSMutableDictionary" key="actions">
+						<string key="NS.key.0">onSysMenuCommand:</string>
+						<string key="NS.object.0">id</string>
+					</object>
+					<object class="NSMutableDictionary" key="actionInfosByName">
+						<string key="NS.key.0">onSysMenuCommand:</string>
+						<object class="IBActionInfo" key="NS.object.0">
+							<string key="name">onSysMenuCommand:</string>
+							<string key="candidateClassName">id</string>
+						</object>
+					</object>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="782276403">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">../../WDL/swell/swellappmain.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">SWELLApplication</string>
+					<string key="superclassName">NSApplication</string>
+					<reference key="sourceIdentifier" ref="782276403"/>
+				</object>
+			</object>
+			<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSApplication</string>
+					<string key="superclassName">NSResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="467899154">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSApplication.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSApplication</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="531531874">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSApplicationScripting.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSApplication</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="367190903">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSColorPanel.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSApplication</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSHelpManager.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSApplication</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSPageLayout.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSApplication</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSUserInterfaceItemSearching.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSFontManager</string>
+					<string key="superclassName">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="1069687567">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSFontManager.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSMenu</string>
+					<string key="superclassName">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="789294279">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSMenu.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSMenuItem</string>
+					<string key="superclassName">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="748766719">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSMenuItem.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSAccessibility.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<reference key="sourceIdentifier" ref="467899154"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<reference key="sourceIdentifier" ref="531531874"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<reference key="sourceIdentifier" ref="367190903"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSControl.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSDictionaryController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSDragging.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<reference key="sourceIdentifier" ref="1069687567"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSFontPanel.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSKeyValueBinding.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<reference key="sourceIdentifier" ref="789294279"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSNibLoading.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSOutlineView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSPasteboard.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSSavePanel.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSTableView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSToolbarItem.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="678812543">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSArchiver.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSClassDescription.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSObjectScripting.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSPortCoder.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSScriptClassDescription.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSScriptKeyValueCoding.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSScriptObjectSpecifiers.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSScriptWhoseTests.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURLDownload.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSInterfaceStyle.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSResponder</string>
+					<string key="superclassName">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSResponder.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSClipView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSView</string>
+					<reference key="sourceIdentifier" ref="748766719"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSRulerView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSView</string>
+					<string key="superclassName">NSResponder</string>
+					<reference key="sourceIdentifier" ref="678812543"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSWindow</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSDrawer.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSWindow</string>
+					<string key="superclassName">NSResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSWindow.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSWindow</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">AppKit.framework/Headers/NSWindowScripting.h</string>
+					</object>
+				</object>
+			</object>
+		</object>
+		<int key="IBDocument.localizationMode">0</int>
+		<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
+			<integer value="1050" key="NS.object.0"/>
+		</object>
+		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
+			<integer value="1050" key="NS.object.0"/>
+		</object>
+		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
+			<integer value="3000" key="NS.object.0"/>
+		</object>
+		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+		<string key="IBDocument.LastKnownRelativeProjectPath">../../AccessiblePeakMeter.xcodeproj</string>
+		<int key="IBDocument.defaultPropertyAccessControl">3</int>
+		<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="NSArray" key="dict.sortedKeys">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<string>NSMenuCheckmark</string>
+				<string>NSMenuMixedState</string>
+			</object>
+			<object class="NSMutableArray" key="dict.values">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<string>{9, 8}</string>
+				<string>{7, 2}</string>
+			</object>
+		</object>
+	</data>
+</archive>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/FlipsideView.xib	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,680 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+	<data>
+		<int key="IBDocument.SystemTarget">1056</int>
+		<string key="IBDocument.SystemVersion">10K540</string>
+		<string key="IBDocument.InterfaceBuilderVersion">851</string>
+		<string key="IBDocument.AppKitVersion">1038.36</string>
+		<string key="IBDocument.HIToolboxVersion">461.00</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+			<string key="NS.object.0">141</string>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<integer value="40"/>
+		</object>
+		<object class="NSArray" key="IBDocument.PluginDependencies">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+		</object>
+		<object class="NSMutableDictionary" key="IBDocument.Metadata">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="NSArray" key="dict.sortedKeys" id="0">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+			<object class="NSMutableArray" key="dict.values">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="IBProxyObject" id="372490531">
+				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+			</object>
+			<object class="IBProxyObject" id="340535442">
+				<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+			</object>
+			<object class="IBUIView" id="249263867">
+				<reference key="NSNextResponder"/>
+				<int key="NSvFlags">274</int>
+				<object class="NSMutableArray" key="NSSubviews">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<object class="IBUINavigationBar" id="871675769">
+						<reference key="NSNextResponder" ref="249263867"/>
+						<int key="NSvFlags">290</int>
+						<string key="NSFrameSize">{320, 44}</string>
+						<reference key="NSSuperview" ref="249263867"/>
+						<bool key="IBUIOpaque">NO</bool>
+						<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+						<int key="IBUIBarStyle">1</int>
+						<object class="NSArray" key="IBUIItems">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<object class="IBUINavigationItem" id="553200710">
+								<reference key="IBUINavigationBar" ref="871675769"/>
+								<string key="IBUITitle">Settings</string>
+								<object class="IBUIBarButtonItem" key="IBUILeftBarButtonItem" id="854562692">
+									<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+									<int key="IBUIStyle">1</int>
+									<reference key="IBUINavigationItem" ref="553200710"/>
+									<int key="IBUISystemItemIdentifier">0</int>
+								</object>
+								<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+							</object>
+						</object>
+					</object>
+					<object class="IBUISegmentedControl" id="874879698">
+						<reference key="NSNextResponder" ref="249263867"/>
+						<int key="NSvFlags">292</int>
+						<string key="NSFrame">{{20, 105}, {207, 44}}</string>
+						<reference key="NSSuperview" ref="249263867"/>
+						<bool key="IBUIOpaque">NO</bool>
+						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+						<int key="IBNumberOfSegments">2</int>
+						<int key="IBSelectedSegmentIndex">1</int>
+						<object class="NSArray" key="IBSegmentTitles">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>22050</string>
+							<string>44100</string>
+						</object>
+						<object class="NSMutableArray" key="IBSegmentWidths">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<real value="0.0"/>
+							<real value="0.0"/>
+						</object>
+						<object class="NSMutableArray" key="IBSegmentEnabledStates">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<boolean value="YES"/>
+							<boolean value="YES"/>
+						</object>
+						<object class="NSMutableArray" key="IBSegmentContentOffsets">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>{0, 0}</string>
+							<string>{0, 0}</string>
+						</object>
+						<object class="NSMutableArray" key="IBSegmentImages">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<object class="NSNull" id="4"/>
+							<reference ref="4"/>
+						</object>
+					</object>
+					<object class="IBUILabel" id="903622552">
+						<reference key="NSNextResponder" ref="249263867"/>
+						<int key="NSvFlags">292</int>
+						<string key="NSFrame">{{20, 65}, {99, 21}}</string>
+						<reference key="NSSuperview" ref="249263867"/>
+						<bool key="IBUIOpaque">NO</bool>
+						<bool key="IBUIClipsSubviews">YES</bool>
+						<int key="IBUIContentMode">7</int>
+						<bool key="IBUIUserInteractionEnabled">NO</bool>
+						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+						<string key="IBUIText">Sample Rate</string>
+						<object class="NSColor" key="IBUITextColor" id="696994608">
+							<int key="NSColorSpace">3</int>
+							<bytes key="NSWhite">MQA</bytes>
+						</object>
+						<reference key="IBUIHighlightedColor" ref="696994608"/>
+						<int key="IBUIBaselineAdjustment">1</int>
+						<float key="IBUIMinimumFontSize">10</float>
+					</object>
+					<object class="IBUILabel" id="590873023">
+						<reference key="NSNextResponder" ref="249263867"/>
+						<int key="NSvFlags">292</int>
+						<string key="NSFrame">{{20, 177}, {99, 21}}</string>
+						<reference key="NSSuperview" ref="249263867"/>
+						<bool key="IBUIOpaque">NO</bool>
+						<bool key="IBUIClipsSubviews">YES</bool>
+						<int key="IBUIContentMode">7</int>
+						<bool key="IBUIUserInteractionEnabled">NO</bool>
+						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+						<string key="IBUIText">Midi Input</string>
+						<reference key="IBUITextColor" ref="696994608"/>
+						<reference key="IBUIHighlightedColor" ref="696994608"/>
+						<int key="IBUIBaselineAdjustment">1</int>
+						<float key="IBUIMinimumFontSize">10</float>
+						<bool key="IBUIEnabled">NO</bool>
+					</object>
+					<object class="IBUILabel" id="484737138">
+						<reference key="NSNextResponder" ref="249263867"/>
+						<int key="NSvFlags">292</int>
+						<string key="NSFrame">{{20, 305}, {99, 21}}</string>
+						<reference key="NSSuperview" ref="249263867"/>
+						<bool key="IBUIOpaque">NO</bool>
+						<bool key="IBUIClipsSubviews">YES</bool>
+						<int key="IBUIContentMode">7</int>
+						<bool key="IBUIUserInteractionEnabled">NO</bool>
+						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+						<string key="IBUIText">Midi Output</string>
+						<reference key="IBUITextColor" ref="696994608"/>
+						<reference key="IBUIHighlightedColor" ref="696994608"/>
+						<int key="IBUIBaselineAdjustment">1</int>
+						<float key="IBUIMinimumFontSize">10</float>
+						<bool key="IBUIEnabled">NO</bool>
+					</object>
+				</object>
+				<string key="NSFrameSize">{320, 460}</string>
+				<reference key="NSSuperview"/>
+				<object class="NSColor" key="IBUIBackgroundColor">
+					<int key="NSColorSpace">3</int>
+					<bytes key="NSWhite">MC4yNQA</bytes>
+					<object class="NSColorSpace" key="NSCustomColorSpace">
+						<int key="NSID">2</int>
+					</object>
+				</object>
+				<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+				<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics">
+					<int key="IBUIStatusBarStyle">2</int>
+				</object>
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+			</object>
+		</object>
+		<object class="IBObjectContainer" key="IBDocument.Objects">
+			<object class="NSMutableArray" key="connectionRecords">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">view</string>
+						<reference key="source" ref="372490531"/>
+						<reference key="destination" ref="249263867"/>
+					</object>
+					<int key="connectionID">41</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchEventConnection" key="connection">
+						<string key="label">done:</string>
+						<reference key="source" ref="854562692"/>
+						<reference key="destination" ref="372490531"/>
+					</object>
+					<int key="connectionID">46</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchEventConnection" key="connection">
+						<string key="label">doSRSegControl</string>
+						<reference key="source" ref="874879698"/>
+						<reference key="destination" ref="340535442"/>
+						<int key="IBEventType">13</int>
+					</object>
+					<int key="connectionID">56</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">samplerateSegControl</string>
+						<reference key="source" ref="372490531"/>
+						<reference key="destination" ref="874879698"/>
+					</object>
+					<int key="connectionID">61</int>
+				</object>
+			</object>
+			<object class="IBMutableOrderedSet" key="objectRecords">
+				<object class="NSArray" key="orderedObjects">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<object class="IBObjectRecord">
+						<int key="objectID">0</int>
+						<reference key="object" ref="0"/>
+						<reference key="children" ref="1000"/>
+						<nil key="parent"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-1</int>
+						<reference key="object" ref="372490531"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">File's Owner</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-2</int>
+						<reference key="object" ref="340535442"/>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">40</int>
+						<reference key="object" ref="249263867"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="871675769"/>
+							<reference ref="903622552"/>
+							<reference ref="484737138"/>
+							<reference ref="590873023"/>
+							<reference ref="874879698"/>
+						</object>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">42</int>
+						<reference key="object" ref="871675769"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="553200710"/>
+						</object>
+						<reference key="parent" ref="249263867"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">43</int>
+						<reference key="object" ref="553200710"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="854562692"/>
+						</object>
+						<reference key="parent" ref="871675769"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">44</int>
+						<reference key="object" ref="854562692"/>
+						<reference key="parent" ref="553200710"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">47</int>
+						<reference key="object" ref="874879698"/>
+						<reference key="parent" ref="249263867"/>
+						<string key="objectName">SR switch</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">48</int>
+						<reference key="object" ref="903622552"/>
+						<reference key="parent" ref="249263867"/>
+						<string key="objectName">SR label</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">58</int>
+						<reference key="object" ref="590873023"/>
+						<reference key="parent" ref="249263867"/>
+						<string key="objectName">SR label</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">59</int>
+						<reference key="object" ref="484737138"/>
+						<reference key="parent" ref="249263867"/>
+						<string key="objectName">SR label</string>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="flattenedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="NSArray" key="dict.sortedKeys">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>-1.CustomClassName</string>
+					<string>-2.CustomClassName</string>
+					<string>40.IBEditorWindowLastContentRect</string>
+					<string>40.IBPluginDependency</string>
+					<string>40.IBViewBoundsToFrameTransform</string>
+					<string>42.IBPluginDependency</string>
+					<string>43.IBPluginDependency</string>
+					<string>44.IBPluginDependency</string>
+					<string>47.IBPluginDependency</string>
+					<string>47.IBViewBoundsToFrameTransform</string>
+					<string>48.IBPluginDependency</string>
+					<string>48.IBViewBoundsToFrameTransform</string>
+					<string>58.IBPluginDependency</string>
+					<string>58.IBViewBoundsToFrameTransform</string>
+					<string>59.IBPluginDependency</string>
+					<string>59.IBViewBoundsToFrameTransform</string>
+				</object>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>FlipsideViewController</string>
+					<string>UIResponder</string>
+					<string>{{496, 405}, {320, 480}}</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAAAAAAAAw+UAAA</bytes>
+					</object>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBoAAAwxMAAA</bytes>
+					</object>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABC3AAAwtIAAA</bytes>
+					</object>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBoAAAw0QAAA</bytes>
+					</object>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABBoAAAw6IAAA</bytes>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="unlocalizedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="activeLocalization"/>
+			<object class="NSMutableDictionary" key="localizations">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="sourceID"/>
+			<int key="maxID">61</int>
+		</object>
+		<object class="IBClassDescriber" key="IBDocument.Classes">
+			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">FlipsideViewController</string>
+					<string key="superclassName">UIViewController</string>
+					<object class="NSMutableDictionary" key="actions">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<object class="NSArray" key="dict.sortedKeys">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>doSRSegControl</string>
+							<string>done:</string>
+						</object>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>id</string>
+							<string>id</string>
+						</object>
+					</object>
+					<object class="NSMutableDictionary" key="actionInfosByName">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<object class="NSArray" key="dict.sortedKeys">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>doSRSegControl</string>
+							<string>done:</string>
+						</object>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<object class="IBActionInfo">
+								<string key="name">doSRSegControl</string>
+								<string key="candidateClassName">id</string>
+							</object>
+							<object class="IBActionInfo">
+								<string key="name">done:</string>
+								<string key="candidateClassName">id</string>
+							</object>
+						</object>
+					</object>
+					<object class="NSMutableDictionary" key="outlets">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<object class="NSArray" key="dict.sortedKeys">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>delegate</string>
+							<string>samplerateSegControl</string>
+						</object>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>id</string>
+							<string>UISegmentedControl</string>
+						</object>
+					</object>
+					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<object class="NSArray" key="dict.sortedKeys">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>delegate</string>
+							<string>samplerateSegControl</string>
+						</object>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<object class="IBToOneOutletInfo">
+								<string key="name">delegate</string>
+								<string key="candidateClassName">id</string>
+							</object>
+							<object class="IBToOneOutletInfo">
+								<string key="name">samplerateSegControl</string>
+								<string key="candidateClassName">UISegmentedControl</string>
+							</object>
+						</object>
+					</object>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">ios_wrapper/FlipsideViewController.h</string>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="292697028">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIBarButtonItem</string>
+					<string key="superclassName">UIBarItem</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIBarButtonItem.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIBarItem</string>
+					<string key="superclassName">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIBarItem.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIControl</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UILabel</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UILabel.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UINavigationBar</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="522138517">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINavigationBar.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UINavigationItem</string>
+					<string key="superclassName">NSObject</string>
+					<reference key="sourceIdentifier" ref="522138517"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIResponder</string>
+					<string key="superclassName">NSObject</string>
+					<reference key="sourceIdentifier" ref="292697028"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISearchBar</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISearchDisplayController</string>
+					<string key="superclassName">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISegmentedControl</string>
+					<string key="superclassName">UIControl</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISegmentedControl.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+					</object>
+				</object>
+			</object>
+		</object>
+		<int key="IBDocument.localizationMode">0</int>
+		<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+			<integer value="1056" key="NS.object.0"/>
+		</object>
+		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+			<integer value="3100" key="NS.object.0"/>
+		</object>
+		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+		<string key="IBDocument.LastKnownRelativeProjectPath">../AccessiblePeakMeter-IOS.xcodeproj</string>
+		<int key="IBDocument.defaultPropertyAccessControl">3</int>
+		<string key="IBCocoaTouchPluginVersion">141</string>
+	</data>
+</archive>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/MainView.xib	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,523 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+	<data>
+		<int key="IBDocument.SystemTarget">1056</int>
+		<string key="IBDocument.SystemVersion">10K549</string>
+		<string key="IBDocument.InterfaceBuilderVersion">851</string>
+		<string key="IBDocument.AppKitVersion">1038.36</string>
+		<string key="IBDocument.HIToolboxVersion">461.00</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+			<string key="NS.object.0">141</string>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<integer value="34"/>
+		</object>
+		<object class="NSArray" key="IBDocument.PluginDependencies">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+		</object>
+		<object class="NSMutableDictionary" key="IBDocument.Metadata">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="NSArray" key="dict.sortedKeys" id="0">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+			<object class="NSMutableArray" key="dict.values">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="IBProxyObject" id="372490531">
+				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+			</object>
+			<object class="IBProxyObject" id="815241450">
+				<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+			</object>
+			<object class="IBUIView" id="883825266">
+				<reference key="NSNextResponder"/>
+				<int key="NSvFlags">274</int>
+				<object class="NSMutableArray" key="NSSubviews">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<object class="IBUIButton" id="558454645">
+						<reference key="NSNextResponder" ref="883825266"/>
+						<int key="NSvFlags">265</int>
+						<string key="NSFrame">{{282, 421}, {18, 19}}</string>
+						<reference key="NSSuperview" ref="883825266"/>
+						<bool key="IBUIOpaque">NO</bool>
+						<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+						<int key="IBUIContentHorizontalAlignment">0</int>
+						<int key="IBUIContentVerticalAlignment">0</int>
+						<object class="NSFont" key="IBUIFont">
+							<string key="NSName">Helvetica-BoldOblique</string>
+							<double key="NSSize">15</double>
+							<int key="NSfFlags">16</int>
+						</object>
+						<int key="IBUIButtonType">3</int>
+						<bool key="IBUIShowsTouchWhenHighlighted">YES</bool>
+						<object class="NSColor" key="IBUIHighlightedTitleColor">
+							<int key="NSColorSpace">1</int>
+							<bytes key="NSRGB">MSAxIDEAA</bytes>
+						</object>
+						<object class="NSColor" key="IBUINormalTitleColor">
+							<int key="NSColorSpace">1</int>
+							<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+						</object>
+						<object class="NSColor" key="IBUINormalTitleShadowColor">
+							<int key="NSColorSpace">3</int>
+							<bytes key="NSWhite">MAA</bytes>
+						</object>
+					</object>
+					<object class="IBUIButton" id="530406944">
+						<reference key="NSNextResponder" ref="883825266"/>
+						<int key="NSvFlags">269</int>
+						<string key="NSFrame">{{95, 412}, {127, 37}}</string>
+						<reference key="NSSuperview" ref="883825266"/>
+						<bool key="IBUIOpaque">NO</bool>
+						<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+						<int key="IBUIContentHorizontalAlignment">0</int>
+						<int key="IBUIContentVerticalAlignment">0</int>
+						<object class="NSFont" key="IBUIFont">
+							<string key="NSName">Helvetica-Bold</string>
+							<double key="NSSize">15</double>
+							<int key="NSfFlags">16</int>
+						</object>
+						<int key="IBUIButtonType">1</int>
+						<string key="IBUINormalTitle">Play Midi Note</string>
+						<object class="NSColor" key="IBUIHighlightedTitleColor">
+							<int key="NSColorSpace">3</int>
+							<bytes key="NSWhite">MQA</bytes>
+						</object>
+						<object class="NSColor" key="IBUINormalTitleColor">
+							<int key="NSColorSpace">1</int>
+							<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+						</object>
+						<object class="NSColor" key="IBUINormalTitleShadowColor">
+							<int key="NSColorSpace">3</int>
+							<bytes key="NSWhite">MC41AA</bytes>
+						</object>
+					</object>
+				</object>
+				<string key="NSFrameSize">{320, 460}</string>
+				<reference key="NSSuperview"/>
+				<object class="NSColor" key="IBUIBackgroundColor">
+					<int key="NSColorSpace">3</int>
+					<bytes key="NSWhite">MC4yNQA</bytes>
+					<object class="NSColorSpace" key="NSCustomColorSpace">
+						<int key="NSID">2</int>
+					</object>
+				</object>
+				<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+				<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+			</object>
+		</object>
+		<object class="IBObjectContainer" key="IBDocument.Objects">
+			<object class="NSMutableArray" key="connectionRecords">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">view</string>
+						<reference key="source" ref="372490531"/>
+						<reference key="destination" ref="883825266"/>
+					</object>
+					<int key="connectionID">35</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchEventConnection" key="connection">
+						<string key="label">showInfo:</string>
+						<reference key="source" ref="558454645"/>
+						<reference key="destination" ref="372490531"/>
+						<int key="IBEventType">7</int>
+					</object>
+					<int key="connectionID">38</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchEventConnection" key="connection">
+						<string key="label">noteOnPressed:</string>
+						<reference key="source" ref="530406944"/>
+						<reference key="destination" ref="372490531"/>
+						<int key="IBEventType">1</int>
+					</object>
+					<int key="connectionID">41</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchEventConnection" key="connection">
+						<string key="label">noteOffPressed:</string>
+						<reference key="source" ref="530406944"/>
+						<reference key="destination" ref="372490531"/>
+						<int key="IBEventType">8</int>
+					</object>
+					<int key="connectionID">43</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchEventConnection" key="connection">
+						<string key="label">noteOffPressed:</string>
+						<reference key="source" ref="530406944"/>
+						<reference key="destination" ref="372490531"/>
+						<int key="IBEventType">7</int>
+					</object>
+					<int key="connectionID">44</int>
+				</object>
+			</object>
+			<object class="IBMutableOrderedSet" key="objectRecords">
+				<object class="NSArray" key="orderedObjects">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<object class="IBObjectRecord">
+						<int key="objectID">0</int>
+						<reference key="object" ref="0"/>
+						<reference key="children" ref="1000"/>
+						<nil key="parent"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-1</int>
+						<reference key="object" ref="372490531"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">File's Owner</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-2</int>
+						<reference key="object" ref="815241450"/>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">34</int>
+						<reference key="object" ref="883825266"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<reference ref="558454645"/>
+							<reference ref="530406944"/>
+						</object>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">36</int>
+						<reference key="object" ref="558454645"/>
+						<reference key="parent" ref="883825266"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">39</int>
+						<reference key="object" ref="530406944"/>
+						<reference key="parent" ref="883825266"/>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="flattenedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="NSArray" key="dict.sortedKeys">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>-1.CustomClassName</string>
+					<string>-2.CustomClassName</string>
+					<string>34.IBEditorWindowLastContentRect</string>
+					<string>34.IBPluginDependency</string>
+					<string>36.IBPluginDependency</string>
+					<string>39.IBPluginDependency</string>
+					<string>39.IBViewBoundsToFrameTransform</string>
+				</object>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>MainViewController</string>
+					<string>UIResponder</string>
+					<string>{{373, 233}, {320, 480}}</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<object class="NSAffineTransform">
+						<bytes key="NSTransformStruct">P4AAAL+AAABCwAAAw3cAAA</bytes>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="unlocalizedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="activeLocalization"/>
+			<object class="NSMutableDictionary" key="localizations">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="sourceID"/>
+			<int key="maxID">44</int>
+		</object>
+		<object class="IBClassDescriber" key="IBDocument.Classes">
+			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">MainViewController</string>
+					<string key="superclassName">UIViewController</string>
+					<object class="NSMutableDictionary" key="actions">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<object class="NSArray" key="dict.sortedKeys">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>noteOffPressed:</string>
+							<string>noteOnPressed:</string>
+							<string>showInfo:</string>
+							<string>sliderValueChanged:</string>
+						</object>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>UIButton</string>
+							<string>UIButton</string>
+							<string>id</string>
+							<string>UISlider</string>
+						</object>
+					</object>
+					<object class="NSMutableDictionary" key="actionInfosByName">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<object class="NSArray" key="dict.sortedKeys">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>noteOffPressed:</string>
+							<string>noteOnPressed:</string>
+							<string>showInfo:</string>
+							<string>sliderValueChanged:</string>
+						</object>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<object class="IBActionInfo">
+								<string key="name">noteOffPressed:</string>
+								<string key="candidateClassName">UIButton</string>
+							</object>
+							<object class="IBActionInfo">
+								<string key="name">noteOnPressed:</string>
+								<string key="candidateClassName">UIButton</string>
+							</object>
+							<object class="IBActionInfo">
+								<string key="name">showInfo:</string>
+								<string key="candidateClassName">id</string>
+							</object>
+							<object class="IBActionInfo">
+								<string key="name">sliderValueChanged:</string>
+								<string key="candidateClassName">UISlider</string>
+							</object>
+						</object>
+					</object>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">ios_wrapper/MainViewController.h</string>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="990327596">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIButton</string>
+					<string key="superclassName">UIControl</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIButton.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIControl</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIResponder</string>
+					<string key="superclassName">NSObject</string>
+					<reference key="sourceIdentifier" ref="990327596"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISearchBar</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISearchDisplayController</string>
+					<string key="superclassName">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISlider</string>
+					<string key="superclassName">UIControl</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISlider.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+					</object>
+				</object>
+			</object>
+		</object>
+		<int key="IBDocument.localizationMode">0</int>
+		<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+			<integer value="1056" key="NS.object.0"/>
+		</object>
+		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+			<integer value="3100" key="NS.object.0"/>
+		</object>
+		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+		<string key="IBDocument.LastKnownRelativeProjectPath">../AccessiblePeakMeter-ios.xcodeproj</string>
+		<int key="IBDocument.defaultPropertyAccessControl">3</int>
+		<string key="IBCocoaTouchPluginVersion">141</string>
+	</data>
+</archive>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/MainWindow.xib	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,460 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+	<data>
+		<int key="IBDocument.SystemTarget">1024</int>
+		<string key="IBDocument.SystemVersion">10D571</string>
+		<string key="IBDocument.InterfaceBuilderVersion">786</string>
+		<string key="IBDocument.AppKitVersion">1038.29</string>
+		<string key="IBDocument.HIToolboxVersion">460.00</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+			<string key="NS.object.0">112</string>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<integer value="2"/>
+			<integer value="22"/>
+		</object>
+		<object class="NSArray" key="IBDocument.PluginDependencies">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+		</object>
+		<object class="NSMutableDictionary" key="IBDocument.Metadata">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="NSArray" key="dict.sortedKeys" id="0">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+			<object class="NSMutableArray" key="dict.values">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+		</object>
+		<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="IBProxyObject" id="841351856">
+				<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+			</object>
+			<object class="IBProxyObject" id="71653367">
+				<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+			</object>
+			<object class="IBUICustomObject" id="664661524">
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+			</object>
+			<object class="IBUIWindow" id="380026005">
+				<reference key="NSNextResponder"/>
+				<int key="NSvFlags">1316</int>
+				<object class="NSPSMatrix" key="NSFrameMatrix"/>
+				<string key="NSFrameSize">{320, 480}</string>
+				<reference key="NSSuperview"/>
+				<object class="NSColor" key="IBUIBackgroundColor">
+					<int key="NSColorSpace">1</int>
+					<bytes key="NSRGB">MCAwIDAAA</bytes>
+				</object>
+				<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+				<bool key="IBUIMultipleTouchEnabled">YES</bool>
+				<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+				<bool key="IBUIResizesToFullScreen">YES</bool>
+			</object>
+			<object class="IBUIViewController" id="919822394">
+				<string key="IBUINibName">MainView</string>
+				<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+				<object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+					<int key="interfaceOrientation">1</int>
+				</object>
+				<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+				<bool key="IBUIHorizontal">NO</bool>
+			</object>
+		</object>
+		<object class="IBObjectContainer" key="IBDocument.Objects">
+			<object class="NSMutableArray" key="connectionRecords">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">window</string>
+						<reference key="source" ref="664661524"/>
+						<reference key="destination" ref="380026005"/>
+					</object>
+					<int key="connectionID">5</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">mainViewController</string>
+						<reference key="source" ref="664661524"/>
+						<reference key="destination" ref="919822394"/>
+					</object>
+					<int key="connectionID">24</int>
+				</object>
+				<object class="IBConnectionRecord">
+					<object class="IBCocoaTouchOutletConnection" key="connection">
+						<string key="label">delegate</string>
+						<reference key="source" ref="841351856"/>
+						<reference key="destination" ref="664661524"/>
+					</object>
+					<int key="connectionID">26</int>
+				</object>
+			</object>
+			<object class="IBMutableOrderedSet" key="objectRecords">
+				<object class="NSArray" key="orderedObjects">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<object class="IBObjectRecord">
+						<int key="objectID">0</int>
+						<reference key="object" ref="0"/>
+						<reference key="children" ref="1000"/>
+						<nil key="parent"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">2</int>
+						<reference key="object" ref="380026005"/>
+						<object class="NSMutableArray" key="children">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+						</object>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-1</int>
+						<reference key="object" ref="841351856"/>
+						<reference key="parent" ref="0"/>
+						<string key="objectName">File's Owner</string>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">3</int>
+						<reference key="object" ref="664661524"/>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">-2</int>
+						<reference key="object" ref="71653367"/>
+						<reference key="parent" ref="0"/>
+					</object>
+					<object class="IBObjectRecord">
+						<int key="objectID">22</int>
+						<reference key="object" ref="919822394"/>
+						<reference key="parent" ref="0"/>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="flattenedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="NSArray" key="dict.sortedKeys">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>-1.CustomClassName</string>
+					<string>-2.CustomClassName</string>
+					<string>2.IBAttributePlaceholdersKey</string>
+					<string>2.IBEditorWindowLastContentRect</string>
+					<string>2.IBPluginDependency</string>
+					<string>22.CustomClassName</string>
+					<string>22.IBEditorWindowLastContentRect</string>
+					<string>22.IBPluginDependency</string>
+					<string>3.CustomClassName</string>
+					<string>3.IBPluginDependency</string>
+				</object>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+					<string>UIApplication</string>
+					<string>UIResponder</string>
+					<object class="NSMutableDictionary">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<reference key="dict.sortedKeys" ref="0"/>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+						</object>
+					</object>
+					<string>{{190, 376}, {320, 480}}</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<string>MainViewController</string>
+					<string>{{0, 905}, {320, 480}}</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+					<string>AccessiblePeakMeterAppDelegate</string>
+					<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+				</object>
+			</object>
+			<object class="NSMutableDictionary" key="unlocalizedProperties">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="activeLocalization"/>
+			<object class="NSMutableDictionary" key="localizations">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<reference key="dict.sortedKeys" ref="0"/>
+				<object class="NSMutableArray" key="dict.values">
+					<bool key="EncodedWithXMLCoder">YES</bool>
+				</object>
+			</object>
+			<nil key="sourceID"/>
+			<int key="maxID">26</int>
+		</object>
+		<object class="IBClassDescriber" key="IBDocument.Classes">
+			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">MainViewController</string>
+					<string key="superclassName">UIViewController</string>
+					<object class="NSMutableDictionary" key="actions">
+						<string key="NS.key.0">showInfo:</string>
+						<string key="NS.object.0">id</string>
+					</object>
+					<object class="NSMutableDictionary" key="actionInfosByName">
+						<string key="NS.key.0">showInfo:</string>
+						<object class="IBActionInfo" key="NS.object.0">
+							<string key="name">showInfo:</string>
+							<string key="candidateClassName">id</string>
+						</object>
+					</object>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">Classes/MainViewController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIWindow</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBUserSource</string>
+						<string key="minorKey"/>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">AccessiblePeakMeterAppDelegate</string>
+					<string key="superclassName">NSObject</string>
+					<object class="NSMutableDictionary" key="outlets">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<object class="NSArray" key="dict.sortedKeys">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>mainViewController</string>
+							<string>window</string>
+						</object>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>MainViewController</string>
+							<string>UIWindow</string>
+						</object>
+					</object>
+					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
+						<bool key="EncodedWithXMLCoder">YES</bool>
+						<object class="NSArray" key="dict.sortedKeys">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<string>mainViewController</string>
+							<string>window</string>
+						</object>
+						<object class="NSMutableArray" key="dict.values">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<object class="IBToOneOutletInfo">
+								<string key="name">mainViewController</string>
+								<string key="candidateClassName">MainViewController</string>
+							</object>
+							<object class="IBToOneOutletInfo">
+								<string key="name">window</string>
+								<string key="candidateClassName">UIWindow</string>
+							</object>
+						</object>
+					</object>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBProjectSource</string>
+						<string key="minorKey">Classes/AccessiblePeakMeterAppDelegate.h</string>
+					</object>
+				</object>
+			</object>
+			<object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier" id="221394588">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIApplication</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIApplication.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIResponder</string>
+					<string key="superclassName">NSObject</string>
+					<reference key="sourceIdentifier" ref="221394588"/>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISearchBar</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UISearchDisplayController</string>
+					<string key="superclassName">NSObject</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIView</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIViewController</string>
+					<string key="superclassName">UIResponder</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+					</object>
+				</object>
+				<object class="IBPartialClassDescription">
+					<string key="className">UIWindow</string>
+					<string key="superclassName">UIView</string>
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
+						<string key="majorKey">IBFrameworkSource</string>
+						<string key="minorKey">UIKit.framework/Headers/UIWindow.h</string>
+					</object>
+				</object>
+			</object>
+		</object>
+		<int key="IBDocument.localizationMode">0</int>
+		<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+			<integer value="1024" key="NS.object.0"/>
+		</object>
+		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+			<integer value="3100" key="NS.object.0"/>
+		</object>
+		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+		<string key="IBDocument.LastKnownRelativeProjectPath">AccessiblePeakMeter.xcodeproj</string>
+		<int key="IBDocument.defaultPropertyAccessControl">3</int>
+		<string key="IBCocoaTouchPluginVersion">112</string>
+	</data>
+</archive>
Binary file resources/img/bg.png has changed
Binary file resources/img/fader.png has changed
Binary file resources/img/knob.png has changed
Binary file resources/img/switch.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/include/ADSR.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,179 @@
+#ifndef STK_ADSR_H
+#define STK_ADSR_H
+
+#include "Generator.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class ADSR
+    \brief STK ADSR envelope class.
+
+    This class implements a traditional ADSR (Attack, Decay, Sustain,
+    Release) envelope.  It responds to simple keyOn and keyOff
+    messages, keeping track of its state.  The \e state = ADSR::IDLE
+    before being triggered and after the envelope value reaches 0.0 in
+    the ADSR::RELEASE state.  All rate, target and level settings must
+    be non-negative.  All time settings are in seconds and must be
+    positive.
+
+    by Perry R. Cook and Gary P. Scavone, 1995--2014.
+*/
+/***************************************************/
+
+class ADSR : public Generator
+{
+ public:
+
+  //! ADSR envelope states.
+  enum {
+    ATTACK,   /*!< Attack */
+    DECAY,    /*!< Decay */
+    SUSTAIN,  /*!< Sustain */
+    RELEASE,  /*!< Release */
+    IDLE      /*!< Before attack / after release */
+  };
+
+  //! Default constructor.
+  ADSR( void );
+
+  //! Class destructor.
+  ~ADSR( void );
+
+  //! Set target = 1, state = \e ADSR::ATTACK.
+  void keyOn( void );
+
+  //! Set target = 0, state = \e ADSR::RELEASE.
+  void keyOff( void );
+
+  //! Set the attack rate (gain / sample).
+  void setAttackRate( StkFloat rate );
+
+  //! Set the target value for the attack (default = 1.0).
+  void setAttackTarget( StkFloat target );
+
+  //! Set the decay rate (gain / sample).
+  void setDecayRate( StkFloat rate );
+
+  //! Set the sustain level.
+  void setSustainLevel( StkFloat level );
+
+  //! Set the release rate (gain / sample).
+  void setReleaseRate( StkFloat rate );
+
+  //! Set the attack rate based on a time duration (seconds).
+  void setAttackTime( StkFloat time );
+
+  //! Set the decay rate based on a time duration (seconds).
+  void setDecayTime( StkFloat time );
+
+  //! Set the release rate based on a time duration (seconds).
+  void setReleaseTime( StkFloat time );
+
+  //! Set sustain level and attack, decay, and release time durations (seconds).
+  void setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime );
+
+  //! Set a sustain target value and attack or decay from current value to target.
+  void setTarget( StkFloat target );
+
+  //! Return the current envelope \e state (ATTACK, DECAY, SUSTAIN, RELEASE, IDLE).
+  int getState( void ) const { return state_; };
+
+  //! Set to state = ADSR::SUSTAIN with current and target values of \e value.
+  void setValue( StkFloat value );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Compute and return one output sample.
+  StkFloat tick( void );
+
+  //! Fill a channel of the StkFrames object with computed outputs.
+  /*!
+    The \c channel argument must be less than the number of
+    channels in the StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+ protected:  
+
+  void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+
+  int state_;
+  StkFloat value_;
+  StkFloat target_;
+  StkFloat attackRate_;
+  StkFloat decayRate_;
+  StkFloat releaseRate_;
+  StkFloat releaseTime_;
+  StkFloat sustainLevel_;
+};
+
+inline StkFloat ADSR :: tick( void )
+{
+  switch ( state_ ) {
+
+  case ATTACK:
+    value_ += attackRate_;
+    if ( value_ >= target_ ) {
+      value_ = target_;
+      target_ = sustainLevel_;
+	    state_ = DECAY;
+    }
+    lastFrame_[0] = value_;
+    break;
+
+  case DECAY:
+    if ( value_ > sustainLevel_ ) {
+      value_ -= decayRate_;
+      if ( value_ <= sustainLevel_ ) {
+        value_ = sustainLevel_;
+        state_ = SUSTAIN;
+      }
+    }
+    else {
+      value_ += decayRate_; // attack target < sustain level
+      if ( value_ >= sustainLevel_ ) {
+        value_ = sustainLevel_;
+        state_ = SUSTAIN;
+      }
+    }
+    lastFrame_[0] = value_;
+    break;
+
+  case RELEASE:
+    value_ -= releaseRate_;
+    if ( value_ <= 0.0 ) {
+      value_ = 0.0;
+      state_ = IDLE;
+    }
+    lastFrame_[0] = value_;
+
+  }
+
+  return value_;
+}
+
+inline StkFrames& ADSR :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    oStream_ << "ADSR::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+    *samples = ADSR::tick();
+
+  return frames;
+}
+
+} // stk namespace
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/include/Envelope.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,130 @@
+#ifndef STK_ENVELOPE_H
+#define STK_ENVELOPE_H
+
+#include "Generator.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Envelope
+    \brief STK linear line envelope class.
+
+    This class implements a simple linear line envelope generator
+    which is capable of ramping to an arbitrary target value by a
+    specified \e rate.  It also responds to simple \e keyOn and \e
+    keyOff messages, ramping to 1.0 on keyOn and to 0.0 on keyOff.
+
+    by Perry R. Cook and Gary P. Scavone, 1995--2014.
+*/
+/***************************************************/
+
+class Envelope : public Generator
+{
+ public:
+
+  //! Default constructor.
+  Envelope( void );
+
+  //! Class destructor.
+  ~Envelope( void );
+
+  //! Assignment operator.
+  Envelope& operator= ( const Envelope& e );
+
+  //! Set target = 1.
+  void keyOn( void ) { this->setTarget( 1.0 ); };
+
+  //! Set target = 0.
+  void keyOff( void ) { this->setTarget( 0.0 ); };
+
+  //! Set the \e rate.
+  /*!
+    The \e rate must be positive (though a value of 0.0 is allowed).
+   */
+  void setRate( StkFloat rate );
+
+  //! Set the \e rate based on a positive time duration (seconds).
+  /*!
+    The \e rate is calculated such that the envelope will ramp from
+    a value of 0.0 to 1.0 in the specified time duration.
+   */
+  void setTime( StkFloat time );
+
+  //! Set the target value.
+  void setTarget( StkFloat target );
+
+  //! Set current and target values to \e value.
+  void setValue( StkFloat value );
+
+  //! Return the current envelope \e state (0 = at target, 1 otherwise).
+  int getState( void ) const { return state_; };
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Compute and return one output sample.
+  StkFloat tick( void );
+
+  //! Fill a channel of the StkFrames object with computed outputs.
+  /*!
+    The \c channel argument must be less than the number of
+    channels in the StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+ protected:
+
+  void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+
+  StkFloat value_;
+  StkFloat target_;
+  StkFloat rate_;
+  int state_;
+};
+
+inline StkFloat Envelope :: tick( void )
+{
+  if ( state_ ) {
+    if ( target_ > value_ ) {
+      value_ += rate_;
+      if ( value_ >= target_ ) {
+        value_ = target_;
+        state_ = 0;
+      }
+    }
+    else {
+      value_ -= rate_;
+      if ( value_ <= target_ ) {
+        value_ = target_;
+        state_ = 0;
+      }
+    }
+    lastFrame_[0] = value_;
+  }
+
+  return value_;
+}
+
+inline StkFrames& Envelope :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    oStream_ << "Envelope::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+    *samples = tick();
+
+  return frames;
+}
+
+} // stk namespace
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/include/Generator.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,50 @@
+#ifndef STK_GENERATOR_H
+#define STK_GENERATOR_H
+
+#include "Stk.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Generator
+    \brief STK abstract unit generator parent class.
+
+    This class provides limited common functionality for STK unit
+    generator sample-source subclasses.  It is general enough to
+    support both monophonic and polyphonic output classes.
+
+    by Perry R. Cook and Gary P. Scavone, 1995--2014.
+*/
+/***************************************************/
+
+class Generator : public Stk
+{
+ public:
+
+  //! Class constructor.
+  Generator( void ) { lastFrame_.resize( 1, 1, 0.0 ); };
+
+  //! Return the number of output channels for the class.
+  unsigned int channelsOut( void ) const { return lastFrame_.channels(); };
+
+  //! Return an StkFrames reference to the last output sample frame.
+  const StkFrames& lastFrame( void ) const { return lastFrame_; };
+
+  //! Fill the StkFrames object with computed sample frames, starting at the specified channel.
+  /*!
+    The \c channel argument plus the number of output channels must
+    be less than the number of channels in the StkFrames argument (the
+    first channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ) = 0;
+
+  protected:
+
+  StkFrames lastFrame_;
+};
+
+} // stk namespace
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/include/Mutex.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,74 @@
+#ifndef STK_MUTEX_H
+#define STK_MUTEX_H
+
+#include "Stk.h"
+
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  #include <pthread.h>
+  typedef pthread_mutex_t MUTEX;
+  typedef pthread_cond_t CONDITION;
+
+#elif defined(__OS_WINDOWS__)
+
+  #include <windows.h>
+  #include <process.h>
+  typedef CRITICAL_SECTION MUTEX;
+  typedef HANDLE CONDITION;
+
+#endif
+
+namespace stk {
+
+/***************************************************/
+/*! \class Mutex
+    \brief STK mutex class.
+
+    This class provides a uniform interface for
+    cross-platform mutex use.  On Linux and IRIX
+    systems, the pthread library is used. Under
+    Windows, critical sections are used.
+
+    by Perry R. Cook and Gary P. Scavone, 1995--2014.
+*/
+/***************************************************/
+
+class Mutex : public Stk
+{
+ public:
+  //! Default constructor.
+  Mutex();
+
+  //! Class destructor.
+  ~Mutex();
+
+  //! Lock the mutex.
+  void lock(void);
+
+  //! Unlock the mutex.
+  void unlock(void);
+
+  //! Wait indefinitely on the mutex condition variable.
+  /*!
+    The mutex must be locked before calling this function, and then
+    subsequently unlocked after this function returns.
+   */
+  void wait(void);
+
+  //! Signal the condition variable.
+  /*!
+    The mutex must be locked before calling this function, and then
+    subsequently unlocked after this function returns.
+   */
+  void signal(void);
+
+ protected:
+
+  MUTEX mutex_;
+  CONDITION condition_;
+
+};
+
+} // stk namespace
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/include/RtAudio.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,1162 @@
+/************************************************************************/
+/*! \class RtAudio
+    \brief Realtime audio i/o C++ classes.
+
+    RtAudio provides a common API (Application Programming Interface)
+    for realtime audio input/output across Linux (native ALSA, Jack,
+    and OSS), Macintosh OS X (CoreAudio and Jack), and Windows
+    (DirectSound, ASIO and WASAPI) operating systems.
+
+    RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
+
+    RtAudio: realtime audio i/o C++ classes
+    Copyright (c) 2001-2014 Gary P. Scavone
+
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation files
+    (the "Software"), to deal in the Software without restriction,
+    including without limitation the rights to use, copy, modify, merge,
+    publish, distribute, sublicense, and/or sell copies of the Software,
+    and to permit persons to whom the Software is furnished to do so,
+    subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    Any person wishing to distribute modifications to the Software is
+    asked to send the modifications to the original developer so that
+    they can be incorporated into the canonical version.  This is,
+    however, not a binding provision of this license.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/************************************************************************/
+
+/*!
+  \file RtAudio.h
+ */
+
+#ifndef __RTAUDIO_H
+#define __RTAUDIO_H
+
+#define RTAUDIO_VERSION "4.1.1"
+
+#include <string>
+#include <vector>
+#include <exception>
+#include <iostream>
+
+/*! \typedef typedef unsigned long RtAudioFormat;
+    \brief RtAudio data format type.
+
+    Support for signed integers and floats.  Audio data fed to/from an
+    RtAudio stream is assumed to ALWAYS be in host byte order.  The
+    internal routines will automatically take care of any necessary
+    byte-swapping between the host format and the soundcard.  Thus,
+    endian-ness is not a concern in the following format definitions.
+
+    - \e RTAUDIO_SINT8:   8-bit signed integer.
+    - \e RTAUDIO_SINT16:  16-bit signed integer.
+    - \e RTAUDIO_SINT24:  24-bit signed integer.
+    - \e RTAUDIO_SINT32:  32-bit signed integer.
+    - \e RTAUDIO_FLOAT32: Normalized between plus/minus 1.0.
+    - \e RTAUDIO_FLOAT64: Normalized between plus/minus 1.0.
+*/
+typedef unsigned long RtAudioFormat;
+static const RtAudioFormat RTAUDIO_SINT8 = 0x1;    // 8-bit signed integer.
+static const RtAudioFormat RTAUDIO_SINT16 = 0x2;   // 16-bit signed integer.
+static const RtAudioFormat RTAUDIO_SINT24 = 0x4;   // 24-bit signed integer.
+static const RtAudioFormat RTAUDIO_SINT32 = 0x8;   // 32-bit signed integer.
+static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; // Normalized between plus/minus 1.0.
+static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/minus 1.0.
+
+/*! \typedef typedef unsigned long RtAudioStreamFlags;
+    \brief RtAudio stream option flags.
+
+    The following flags can be OR'ed together to allow a client to
+    make changes to the default stream behavior:
+
+    - \e RTAUDIO_NONINTERLEAVED:   Use non-interleaved buffers (default = interleaved).
+    - \e RTAUDIO_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency.
+    - \e RTAUDIO_HOG_DEVICE:       Attempt grab device for exclusive use.
+    - \e RTAUDIO_ALSA_USE_DEFAULT: Use the "default" PCM device (ALSA only).
+
+    By default, RtAudio streams pass and receive audio data from the
+    client in an interleaved format.  By passing the
+    RTAUDIO_NONINTERLEAVED flag to the openStream() function, audio
+    data will instead be presented in non-interleaved buffers.  In
+    this case, each buffer argument in the RtAudioCallback function
+    will point to a single array of data, with \c nFrames samples for
+    each channel concatenated back-to-back.  For example, the first
+    sample of data for the second channel would be located at index \c
+    nFrames (assuming the \c buffer pointer was recast to the correct
+    data type for the stream).
+
+    Certain audio APIs offer a number of parameters that influence the
+    I/O latency of a stream.  By default, RtAudio will attempt to set
+    these parameters internally for robust (glitch-free) performance
+    (though some APIs, like Windows Direct Sound, make this difficult).
+    By passing the RTAUDIO_MINIMIZE_LATENCY flag to the openStream()
+    function, internal stream settings will be influenced in an attempt
+    to minimize stream latency, though possibly at the expense of stream
+    performance.
+
+    If the RTAUDIO_HOG_DEVICE flag is set, RtAudio will attempt to
+    open the input and/or output stream device(s) for exclusive use.
+    Note that this is not possible with all supported audio APIs.
+
+    If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt 
+    to select realtime scheduling (round-robin) for the callback thread.
+
+    If the RTAUDIO_ALSA_USE_DEFAULT flag is set, RtAudio will attempt to
+    open the "default" PCM device when using the ALSA API. Note that this
+    will override any specified input or output device id.
+*/
+typedef unsigned int RtAudioStreamFlags;
+static const RtAudioStreamFlags RTAUDIO_NONINTERLEAVED = 0x1;    // Use non-interleaved buffers (default = interleaved).
+static const RtAudioStreamFlags RTAUDIO_MINIMIZE_LATENCY = 0x2;  // Attempt to set stream parameters for lowest possible latency.
+static const RtAudioStreamFlags RTAUDIO_HOG_DEVICE = 0x4;        // Attempt grab device and prevent use by others.
+static const RtAudioStreamFlags RTAUDIO_SCHEDULE_REALTIME = 0x8; // Try to select realtime scheduling for callback thread.
+static const RtAudioStreamFlags RTAUDIO_ALSA_USE_DEFAULT = 0x10; // Use the "default" PCM device (ALSA only).
+
+/*! \typedef typedef unsigned long RtAudioStreamStatus;
+    \brief RtAudio stream status (over- or underflow) flags.
+
+    Notification of a stream over- or underflow is indicated by a
+    non-zero stream \c status argument in the RtAudioCallback function.
+    The stream status can be one of the following two options,
+    depending on whether the stream is open for output and/or input:
+
+    - \e RTAUDIO_INPUT_OVERFLOW:   Input data was discarded because of an overflow condition at the driver.
+    - \e RTAUDIO_OUTPUT_UNDERFLOW: The output buffer ran low, likely producing a break in the output sound.
+*/
+typedef unsigned int RtAudioStreamStatus;
+static const RtAudioStreamStatus RTAUDIO_INPUT_OVERFLOW = 0x1;    // Input data was discarded because of an overflow condition at the driver.
+static const RtAudioStreamStatus RTAUDIO_OUTPUT_UNDERFLOW = 0x2;  // The output buffer ran low, likely causing a gap in the output sound.
+
+//! RtAudio callback function prototype.
+/*!
+   All RtAudio clients must create a function of type RtAudioCallback
+   to read and/or write data from/to the audio stream.  When the
+   underlying audio system is ready for new input or output data, this
+   function will be invoked.
+
+   \param outputBuffer For output (or duplex) streams, the client
+          should write \c nFrames of audio sample frames into this
+          buffer.  This argument should be recast to the datatype
+          specified when the stream was opened.  For input-only
+          streams, this argument will be NULL.
+
+   \param inputBuffer For input (or duplex) streams, this buffer will
+          hold \c nFrames of input audio sample frames.  This
+          argument should be recast to the datatype specified when the
+          stream was opened.  For output-only streams, this argument
+          will be NULL.
+
+   \param nFrames The number of sample frames of input or output
+          data in the buffers.  The actual buffer size in bytes is
+          dependent on the data type and number of channels in use.
+
+   \param streamTime The number of seconds that have elapsed since the
+          stream was started.
+
+   \param status If non-zero, this argument indicates a data overflow
+          or underflow condition for the stream.  The particular
+          condition can be determined by comparison with the
+          RtAudioStreamStatus flags.
+
+   \param userData A pointer to optional data provided by the client
+          when opening the stream (default = NULL).
+
+   To continue normal stream operation, the RtAudioCallback function
+   should return a value of zero.  To stop the stream and drain the
+   output buffer, the function should return a value of one.  To abort
+   the stream immediately, the client should return a value of two.
+ */
+typedef int (*RtAudioCallback)( void *outputBuffer, void *inputBuffer,
+                                unsigned int nFrames,
+                                double streamTime,
+                                RtAudioStreamStatus status,
+                                void *userData );
+
+/************************************************************************/
+/*! \class RtAudioError
+    \brief Exception handling class for RtAudio.
+
+    The RtAudioError class is quite simple but it does allow errors to be
+    "caught" by RtAudioError::Type. See the RtAudio documentation to know
+    which methods can throw an RtAudioError.
+*/
+/************************************************************************/
+
+class RtAudioError : public std::exception
+{
+ public:
+  //! Defined RtAudioError types.
+  enum Type {
+    WARNING,           /*!< A non-critical error. */
+    DEBUG_WARNING,     /*!< A non-critical error which might be useful for debugging. */
+    UNSPECIFIED,       /*!< The default, unspecified error type. */
+    NO_DEVICES_FOUND,  /*!< No devices found on system. */
+    INVALID_DEVICE,    /*!< An invalid device ID was specified. */
+    MEMORY_ERROR,      /*!< An error occured during memory allocation. */
+    INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */
+    INVALID_USE,       /*!< The function was called incorrectly. */
+    DRIVER_ERROR,      /*!< A system driver error occured. */
+    SYSTEM_ERROR,      /*!< A system error occured. */
+    THREAD_ERROR       /*!< A thread error occured. */
+  };
+
+  //! The constructor.
+  RtAudioError( const std::string& message, Type type = RtAudioError::UNSPECIFIED ) throw() : message_(message), type_(type) {}
+ 
+  //! The destructor.
+  virtual ~RtAudioError( void ) throw() {}
+
+  //! Prints thrown error message to stderr.
+  virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; }
+
+  //! Returns the thrown error message type.
+  virtual const Type& getType(void) const throw() { return type_; }
+
+  //! Returns the thrown error message string.
+  virtual const std::string& getMessage(void) const throw() { return message_; }
+
+  //! Returns the thrown error message as a c-style string.
+  virtual const char* what( void ) const throw() { return message_.c_str(); }
+
+ protected:
+  std::string message_;
+  Type type_;
+};
+
+//! RtAudio error callback function prototype.
+/*!
+    \param type Type of error.
+    \param errorText Error description.
+ */
+typedef void (*RtAudioErrorCallback)( RtAudioError::Type type, const std::string &errorText );
+
+// **************************************************************** //
+//
+// RtAudio class declaration.
+//
+// RtAudio is a "controller" used to select an available audio i/o
+// interface.  It presents a common API for the user to call but all
+// functionality is implemented by the class RtApi and its
+// subclasses.  RtAudio creates an instance of an RtApi subclass
+// based on the user's API choice.  If no choice is made, RtAudio
+// attempts to make a "logical" API selection.
+//
+// **************************************************************** //
+
+class RtApi;
+
+class RtAudio
+{
+ public:
+
+  //! Audio API specifier arguments.
+  enum Api {
+    UNSPECIFIED,    /*!< Search for a working compiled API. */
+    LINUX_ALSA,     /*!< The Advanced Linux Sound Architecture API. */
+    LINUX_PULSE,    /*!< The Linux PulseAudio API. */
+    LINUX_OSS,      /*!< The Linux Open Sound System API. */
+    UNIX_JACK,      /*!< The Jack Low-Latency Audio Server API. */
+    MACOSX_CORE,    /*!< Macintosh OS-X Core Audio API. */
+    WINDOWS_WASAPI, /*!< The Microsoft WASAPI API. */
+    WINDOWS_ASIO,   /*!< The Steinberg Audio Stream I/O API. */
+    WINDOWS_DS,     /*!< The Microsoft Direct Sound API. */
+    RTAUDIO_DUMMY   /*!< A compilable but non-functional API. */
+  };
+
+  //! The public device information structure for returning queried values.
+  struct DeviceInfo {
+    bool probed;                  /*!< true if the device capabilities were successfully probed. */
+    std::string name;             /*!< Character string device identifier. */
+    unsigned int outputChannels;  /*!< Maximum output channels supported by device. */
+    unsigned int inputChannels;   /*!< Maximum input channels supported by device. */
+    unsigned int duplexChannels;  /*!< Maximum simultaneous input/output channels supported by device. */
+    bool isDefaultOutput;         /*!< true if this is the default output device. */
+    bool isDefaultInput;          /*!< true if this is the default input device. */
+    std::vector<unsigned int> sampleRates; /*!< Supported sample rates (queried from list of standard rates). */
+    RtAudioFormat nativeFormats;  /*!< Bit mask of supported data formats. */
+
+    // Default constructor.
+    DeviceInfo()
+      :probed(false), outputChannels(0), inputChannels(0), duplexChannels(0),
+       isDefaultOutput(false), isDefaultInput(false), nativeFormats(0) {}
+  };
+
+  //! The structure for specifying input or ouput stream parameters.
+  struct StreamParameters {
+    unsigned int deviceId;     /*!< Device index (0 to getDeviceCount() - 1). */
+    unsigned int nChannels;    /*!< Number of channels. */
+    unsigned int firstChannel; /*!< First channel index on device (default = 0). */
+
+    // Default constructor.
+    StreamParameters()
+      : deviceId(0), nChannels(0), firstChannel(0) {}
+  };
+
+  //! The structure for specifying stream options.
+  /*!
+    The following flags can be OR'ed together to allow a client to
+    make changes to the default stream behavior:
+
+    - \e RTAUDIO_NONINTERLEAVED:    Use non-interleaved buffers (default = interleaved).
+    - \e RTAUDIO_MINIMIZE_LATENCY:  Attempt to set stream parameters for lowest possible latency.
+    - \e RTAUDIO_HOG_DEVICE:        Attempt grab device for exclusive use.
+    - \e RTAUDIO_SCHEDULE_REALTIME: Attempt to select realtime scheduling for callback thread.
+    - \e RTAUDIO_ALSA_USE_DEFAULT:  Use the "default" PCM device (ALSA only).
+
+    By default, RtAudio streams pass and receive audio data from the
+    client in an interleaved format.  By passing the
+    RTAUDIO_NONINTERLEAVED flag to the openStream() function, audio
+    data will instead be presented in non-interleaved buffers.  In
+    this case, each buffer argument in the RtAudioCallback function
+    will point to a single array of data, with \c nFrames samples for
+    each channel concatenated back-to-back.  For example, the first
+    sample of data for the second channel would be located at index \c
+    nFrames (assuming the \c buffer pointer was recast to the correct
+    data type for the stream).
+
+    Certain audio APIs offer a number of parameters that influence the
+    I/O latency of a stream.  By default, RtAudio will attempt to set
+    these parameters internally for robust (glitch-free) performance
+    (though some APIs, like Windows Direct Sound, make this difficult).
+    By passing the RTAUDIO_MINIMIZE_LATENCY flag to the openStream()
+    function, internal stream settings will be influenced in an attempt
+    to minimize stream latency, though possibly at the expense of stream
+    performance.
+
+    If the RTAUDIO_HOG_DEVICE flag is set, RtAudio will attempt to
+    open the input and/or output stream device(s) for exclusive use.
+    Note that this is not possible with all supported audio APIs.
+
+    If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt 
+    to select realtime scheduling (round-robin) for the callback thread.
+    The \c priority parameter will only be used if the RTAUDIO_SCHEDULE_REALTIME
+    flag is set. It defines the thread's realtime priority.
+
+    If the RTAUDIO_ALSA_USE_DEFAULT flag is set, RtAudio will attempt to
+    open the "default" PCM device when using the ALSA API. Note that this
+    will override any specified input or output device id.
+
+    The \c numberOfBuffers parameter can be used to control stream
+    latency in the Windows DirectSound, Linux OSS, and Linux Alsa APIs
+    only.  A value of two is usually the smallest allowed.  Larger
+    numbers can potentially result in more robust stream performance,
+    though likely at the cost of stream latency.  The value set by the
+    user is replaced during execution of the RtAudio::openStream()
+    function by the value actually used by the system.
+
+    The \c streamName parameter can be used to set the client name
+    when using the Jack API.  By default, the client name is set to
+    RtApiJack.  However, if you wish to create multiple instances of
+    RtAudio with Jack, each instance must have a unique client name.
+  */
+  struct StreamOptions {
+    RtAudioStreamFlags flags;      /*!< A bit-mask of stream flags (RTAUDIO_NONINTERLEAVED, RTAUDIO_MINIMIZE_LATENCY, RTAUDIO_HOG_DEVICE, RTAUDIO_ALSA_USE_DEFAULT). */
+    unsigned int numberOfBuffers;  /*!< Number of stream buffers. */
+    std::string streamName;        /*!< A stream name (currently used only in Jack). */
+    int priority;                  /*!< Scheduling priority of callback thread (only used with flag RTAUDIO_SCHEDULE_REALTIME). */
+
+    // Default constructor.
+    StreamOptions()
+    : flags(0), numberOfBuffers(0), priority(0) {}
+  };
+
+  //! A static function to determine the current RtAudio version.
+  static std::string getVersion( void ) throw();
+
+  //! A static function to determine the available compiled audio APIs.
+  /*!
+    The values returned in the std::vector can be compared against
+    the enumerated list values.  Note that there can be more than one
+    API compiled for certain operating systems.
+  */
+  static void getCompiledApi( std::vector<RtAudio::Api> &apis ) throw();
+
+  //! The class constructor.
+  /*!
+    The constructor performs minor initialization tasks.  An exception
+    can be thrown if no API support is compiled.
+
+    If no API argument is specified and multiple API support has been
+    compiled, the default order of use is JACK, ALSA, OSS (Linux
+    systems) and ASIO, DS (Windows systems).
+  */
+  RtAudio( RtAudio::Api api=UNSPECIFIED );
+
+  //! The destructor.
+  /*!
+    If a stream is running or open, it will be stopped and closed
+    automatically.
+  */
+  ~RtAudio() throw();
+
+  //! Returns the audio API specifier for the current instance of RtAudio.
+  RtAudio::Api getCurrentApi( void ) throw();
+
+  //! A public function that queries for the number of audio devices available.
+  /*!
+    This function performs a system query of available devices each time it
+    is called, thus supporting devices connected \e after instantiation. If
+    a system error occurs during processing, a warning will be issued. 
+  */
+  unsigned int getDeviceCount( void ) throw();
+
+  //! Return an RtAudio::DeviceInfo structure for a specified device number.
+  /*!
+
+    Any device integer between 0 and getDeviceCount() - 1 is valid.
+    If an invalid argument is provided, an RtAudioError (type = INVALID_USE)
+    will be thrown.  If a device is busy or otherwise unavailable, the
+    structure member "probed" will have a value of "false" and all
+    other members are undefined.  If the specified device is the
+    current default input or output device, the corresponding
+    "isDefault" member will have a value of "true".
+  */
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+
+  //! A function that returns the index of the default output device.
+  /*!
+    If the underlying audio API does not provide a "default
+    device", or if no devices are available, the return value will be
+    0.  Note that this is a valid device identifier and it is the
+    client's responsibility to verify that a device is available
+    before attempting to open a stream.
+  */
+  unsigned int getDefaultOutputDevice( void ) throw();
+
+  //! A function that returns the index of the default input device.
+  /*!
+    If the underlying audio API does not provide a "default
+    device", or if no devices are available, the return value will be
+    0.  Note that this is a valid device identifier and it is the
+    client's responsibility to verify that a device is available
+    before attempting to open a stream.
+  */
+  unsigned int getDefaultInputDevice( void ) throw();
+
+  //! A public function for opening a stream with the specified parameters.
+  /*!
+    An RtAudioError (type = SYSTEM_ERROR) is thrown if a stream cannot be
+    opened with the specified parameters or an error occurs during
+    processing.  An RtAudioError (type = INVALID_USE) is thrown if any
+    invalid device ID or channel number parameters are specified.
+
+    \param outputParameters Specifies output stream parameters to use
+           when opening a stream, including a device ID, number of channels,
+           and starting channel number.  For input-only streams, this
+           argument should be NULL.  The device ID is an index value between
+           0 and getDeviceCount() - 1.
+    \param inputParameters Specifies input stream parameters to use
+           when opening a stream, including a device ID, number of channels,
+           and starting channel number.  For output-only streams, this
+           argument should be NULL.  The device ID is an index value between
+           0 and getDeviceCount() - 1.
+    \param format An RtAudioFormat specifying the desired sample data format.
+    \param sampleRate The desired sample rate (sample frames per second).
+    \param *bufferFrames A pointer to a value indicating the desired
+           internal buffer size in sample frames.  The actual value
+           used by the device is returned via the same pointer.  A
+           value of zero can be specified, in which case the lowest
+           allowable value is determined.
+    \param callback A client-defined function that will be invoked
+           when input data is available and/or output data is needed.
+    \param userData An optional pointer to data that can be accessed
+           from within the callback function.
+    \param options An optional pointer to a structure containing various
+           global stream options, including a list of OR'ed RtAudioStreamFlags
+           and a suggested number of stream buffers that can be used to 
+           control stream latency.  More buffers typically result in more
+           robust performance, though at a cost of greater latency.  If a
+           value of zero is specified, a system-specific median value is
+           chosen.  If the RTAUDIO_MINIMIZE_LATENCY flag bit is set, the
+           lowest allowable value is used.  The actual value used is
+           returned via the structure argument.  The parameter is API dependent.
+    \param errorCallback A client-defined function that will be invoked
+           when an error has occured.
+  */
+  void openStream( RtAudio::StreamParameters *outputParameters,
+                   RtAudio::StreamParameters *inputParameters,
+                   RtAudioFormat format, unsigned int sampleRate,
+                   unsigned int *bufferFrames, RtAudioCallback callback,
+                   void *userData = NULL, RtAudio::StreamOptions *options = NULL, RtAudioErrorCallback errorCallback = NULL );
+
+  //! A function that closes a stream and frees any associated stream memory.
+  /*!
+    If a stream is not open, this function issues a warning and
+    returns (no exception is thrown).
+  */
+  void closeStream( void ) throw();
+
+  //! A function that starts a stream.
+  /*!
+    An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
+    during processing.  An RtAudioError (type = INVALID_USE) is thrown if a
+    stream is not open.  A warning is issued if the stream is already
+    running.
+  */
+  void startStream( void );
+
+  //! Stop a stream, allowing any samples remaining in the output queue to be played.
+  /*!
+    An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
+    during processing.  An RtAudioError (type = INVALID_USE) is thrown if a
+    stream is not open.  A warning is issued if the stream is already
+    stopped.
+  */
+  void stopStream( void );
+
+  //! Stop a stream, discarding any samples remaining in the input/output queue.
+  /*!
+    An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
+    during processing.  An RtAudioError (type = INVALID_USE) is thrown if a
+    stream is not open.  A warning is issued if the stream is already
+    stopped.
+  */
+  void abortStream( void );
+
+  //! Returns true if a stream is open and false if not.
+  bool isStreamOpen( void ) const throw();
+
+  //! Returns true if the stream is running and false if it is stopped or not open.
+  bool isStreamRunning( void ) const throw();
+
+  //! Returns the number of elapsed seconds since the stream was started.
+  /*!
+    If a stream is not open, an RtAudioError (type = INVALID_USE) will be thrown.
+  */
+  double getStreamTime( void );
+
+  //! Set the stream time to a time in seconds greater than or equal to 0.0.
+  /*!
+    If a stream is not open, an RtAudioError (type = INVALID_USE) will be thrown.
+  */
+  void setStreamTime( double time );
+
+  //! Returns the internal stream latency in sample frames.
+  /*!
+    The stream latency refers to delay in audio input and/or output
+    caused by internal buffering by the audio system and/or hardware.
+    For duplex streams, the returned value will represent the sum of
+    the input and output latencies.  If a stream is not open, an
+    RtAudioError (type = INVALID_USE) will be thrown.  If the API does not
+    report latency, the return value will be zero.
+  */
+  long getStreamLatency( void );
+
+ //! Returns actual sample rate in use by the stream.
+ /*!
+   On some systems, the sample rate used may be slightly different
+   than that specified in the stream parameters.  If a stream is not
+   open, an RtAudioError (type = INVALID_USE) will be thrown.
+ */
+  unsigned int getStreamSampleRate( void );
+
+  //! Specify whether warning messages should be printed to stderr.
+  void showWarnings( bool value = true ) throw();
+
+ protected:
+
+  void openRtApi( RtAudio::Api api );
+  RtApi *rtapi_;
+};
+
+// Operating system dependent thread functionality.
+#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_WASAPI__)
+
+  #ifndef NOMINMAX
+    #define NOMINMAX
+  #endif
+  #include <windows.h>
+  #include <process.h>
+
+  typedef uintptr_t ThreadHandle;
+  typedef CRITICAL_SECTION StreamMutex;
+
+#elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
+  // Using pthread library for various flavors of unix.
+  #include <pthread.h>
+
+  typedef pthread_t ThreadHandle;
+  typedef pthread_mutex_t StreamMutex;
+
+#else // Setup for "dummy" behavior
+
+  #define __RTAUDIO_DUMMY__
+  typedef int ThreadHandle;
+  typedef int StreamMutex;
+
+#endif
+
+// This global structure type is used to pass callback information
+// between the private RtAudio stream structure and global callback
+// handling functions.
+struct CallbackInfo {
+  void *object;    // Used as a "this" pointer.
+  ThreadHandle thread;
+  void *callback;
+  void *userData;
+  void *errorCallback;
+  void *apiInfo;   // void pointer for API specific callback information
+  bool isRunning;
+  bool doRealtime;
+  int priority;
+
+  // Default constructor.
+  CallbackInfo()
+  :object(0), callback(0), userData(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false) {}
+};
+
+// **************************************************************** //
+//
+// RtApi class declaration.
+//
+// Subclasses of RtApi contain all API- and OS-specific code necessary
+// to fully implement the RtAudio API.
+//
+// Note that RtApi is an abstract base class and cannot be
+// explicitly instantiated.  The class RtAudio will create an
+// instance of an RtApi subclass (RtApiOss, RtApiAlsa,
+// RtApiJack, RtApiCore, RtApiDs, or RtApiAsio).
+//
+// **************************************************************** //
+
+#pragma pack(push, 1)
+class S24 {
+
+ protected:
+  unsigned char c3[3];
+
+ public:
+  S24() {}
+
+  S24& operator = ( const int& i ) {
+    c3[0] = (i & 0x000000ff);
+    c3[1] = (i & 0x0000ff00) >> 8;
+    c3[2] = (i & 0x00ff0000) >> 16;
+    return *this;
+  }
+
+  S24( const S24& v ) { *this = v; }
+  S24( const double& d ) { *this = (int) d; }
+  S24( const float& f ) { *this = (int) f; }
+  S24( const signed short& s ) { *this = (int) s; }
+  S24( const char& c ) { *this = (int) c; }
+
+  int asInt() {
+    int i = c3[0] | (c3[1] << 8) | (c3[2] << 16);
+    if (i & 0x800000) i |= ~0xffffff;
+    return i;
+  }
+};
+#pragma pack(pop)
+
+#if defined( HAVE_GETTIMEOFDAY )
+  #include <sys/time.h>
+#endif
+
+#include <sstream>
+
+class RtApi
+{
+public:
+
+  RtApi();
+  virtual ~RtApi();
+  virtual RtAudio::Api getCurrentApi( void ) = 0;
+  virtual unsigned int getDeviceCount( void ) = 0;
+  virtual RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) = 0;
+  virtual unsigned int getDefaultInputDevice( void );
+  virtual unsigned int getDefaultOutputDevice( void );
+  void openStream( RtAudio::StreamParameters *outputParameters,
+                   RtAudio::StreamParameters *inputParameters,
+                   RtAudioFormat format, unsigned int sampleRate,
+                   unsigned int *bufferFrames, RtAudioCallback callback,
+                   void *userData, RtAudio::StreamOptions *options,
+                   RtAudioErrorCallback errorCallback );
+  virtual void closeStream( void );
+  virtual void startStream( void ) = 0;
+  virtual void stopStream( void ) = 0;
+  virtual void abortStream( void ) = 0;
+  long getStreamLatency( void );
+  unsigned int getStreamSampleRate( void );
+  virtual double getStreamTime( void );
+  virtual void setStreamTime( double time );
+  bool isStreamOpen( void ) const { return stream_.state != STREAM_CLOSED; }
+  bool isStreamRunning( void ) const { return stream_.state == STREAM_RUNNING; }
+  void showWarnings( bool value ) { showWarnings_ = value; }
+
+
+protected:
+
+  static const unsigned int MAX_SAMPLE_RATES;
+  static const unsigned int SAMPLE_RATES[];
+
+  enum { FAILURE, SUCCESS };
+
+  enum StreamState {
+    STREAM_STOPPED,
+    STREAM_STOPPING,
+    STREAM_RUNNING,
+    STREAM_CLOSED = -50
+  };
+
+  enum StreamMode {
+    OUTPUT,
+    INPUT,
+    DUPLEX,
+    UNINITIALIZED = -75
+  };
+
+  // A protected structure used for buffer conversion.
+  struct ConvertInfo {
+    int channels;
+    int inJump, outJump;
+    RtAudioFormat inFormat, outFormat;
+    std::vector<int> inOffset;
+    std::vector<int> outOffset;
+  };
+
+  // A protected structure for audio streams.
+  struct RtApiStream {
+    unsigned int device[2];    // Playback and record, respectively.
+    void *apiHandle;           // void pointer for API specific stream handle information
+    StreamMode mode;           // OUTPUT, INPUT, or DUPLEX.
+    StreamState state;         // STOPPED, RUNNING, or CLOSED
+    char *userBuffer[2];       // Playback and record, respectively.
+    char *deviceBuffer;
+    bool doConvertBuffer[2];   // Playback and record, respectively.
+    bool userInterleaved;
+    bool deviceInterleaved[2]; // Playback and record, respectively.
+    bool doByteSwap[2];        // Playback and record, respectively.
+    unsigned int sampleRate;
+    unsigned int bufferSize;
+    unsigned int nBuffers;
+    unsigned int nUserChannels[2];    // Playback and record, respectively.
+    unsigned int nDeviceChannels[2];  // Playback and record channels, respectively.
+    unsigned int channelOffset[2];    // Playback and record, respectively.
+    unsigned long latency[2];         // Playback and record, respectively.
+    RtAudioFormat userFormat;
+    RtAudioFormat deviceFormat[2];    // Playback and record, respectively.
+    StreamMutex mutex;
+    CallbackInfo callbackInfo;
+    ConvertInfo convertInfo[2];
+    double streamTime;         // Number of elapsed seconds since the stream started.
+
+#if defined(HAVE_GETTIMEOFDAY)
+    struct timeval lastTickTimestamp;
+#endif
+
+    RtApiStream()
+      :apiHandle(0), deviceBuffer(0) { device[0] = 11111; device[1] = 11111; }
+  };
+
+  typedef S24 Int24;
+  typedef signed short Int16;
+  typedef signed int Int32;
+  typedef float Float32;
+  typedef double Float64;
+
+  std::ostringstream errorStream_;
+  std::string errorText_;
+  bool showWarnings_;
+  RtApiStream stream_;
+  bool firstErrorOccurred_;
+
+  /*!
+    Protected, api-specific method that attempts to open a device
+    with the given parameters.  This function MUST be implemented by
+    all subclasses.  If an error is encountered during the probe, a
+    "warning" message is reported and FAILURE is returned. A
+    successful probe is indicated by a return value of SUCCESS.
+  */
+  virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
+                                unsigned int firstChannel, unsigned int sampleRate,
+                                RtAudioFormat format, unsigned int *bufferSize,
+                                RtAudio::StreamOptions *options );
+
+  //! A protected function used to increment the stream time.
+  void tickStreamTime( void );
+
+  //! Protected common method to clear an RtApiStream structure.
+  void clearStreamInfo();
+
+  /*!
+    Protected common method that throws an RtAudioError (type =
+    INVALID_USE) if a stream is not open.
+  */
+  void verifyStream( void );
+
+  //! Protected common error method to allow global control over error handling.
+  void error( RtAudioError::Type type );
+
+  /*!
+    Protected method used to perform format, channel number, and/or interleaving
+    conversions between the user and device buffers.
+  */
+  void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info );
+
+  //! Protected common method used to perform byte-swapping on buffers.
+  void byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format );
+
+  //! Protected common method that returns the number of bytes for a given format.
+  unsigned int formatBytes( RtAudioFormat format );
+
+  //! Protected common method that sets up the parameters for buffer conversion.
+  void setConvertInfo( StreamMode mode, unsigned int firstChannel );
+};
+
+// **************************************************************** //
+//
+// Inline RtAudio definitions.
+//
+// **************************************************************** //
+
+inline RtAudio::Api RtAudio :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
+inline unsigned int RtAudio :: getDeviceCount( void ) throw() { return rtapi_->getDeviceCount(); }
+inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { return rtapi_->getDeviceInfo( device ); }
+inline unsigned int RtAudio :: getDefaultInputDevice( void ) throw() { return rtapi_->getDefaultInputDevice(); }
+inline unsigned int RtAudio :: getDefaultOutputDevice( void ) throw() { return rtapi_->getDefaultOutputDevice(); }
+inline void RtAudio :: closeStream( void ) throw() { return rtapi_->closeStream(); }
+inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); }
+inline void RtAudio :: stopStream( void )  { return rtapi_->stopStream(); }
+inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); }
+inline bool RtAudio :: isStreamOpen( void ) const throw() { return rtapi_->isStreamOpen(); }
+inline bool RtAudio :: isStreamRunning( void ) const throw() { return rtapi_->isStreamRunning(); }
+inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); }
+inline unsigned int RtAudio :: getStreamSampleRate( void ) { return rtapi_->getStreamSampleRate(); }
+inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); }
+inline void RtAudio :: setStreamTime( double time ) { return rtapi_->setStreamTime( time ); }
+inline void RtAudio :: showWarnings( bool value ) throw() { rtapi_->showWarnings( value ); }
+
+// RtApi Subclass prototypes.
+
+#if defined(__MACOSX_CORE__)
+
+#include <CoreAudio/AudioHardware.h>
+
+class RtApiCore: public RtApi
+{
+public:
+
+  RtApiCore();
+  ~RtApiCore();
+  RtAudio::Api getCurrentApi( void ) { return RtAudio::MACOSX_CORE; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  unsigned int getDefaultOutputDevice( void );
+  unsigned int getDefaultInputDevice( void );
+  void closeStream( void );
+  void startStream( void );
+  void stopStream( void );
+  void abortStream( void );
+  long getStreamLatency( void );
+
+  // This function is intended for internal use only.  It must be
+  // public because it is called by the internal callback handler,
+  // which is not a member of RtAudio.  External use of this function
+  // will most likely produce highly undesireable results!
+  bool callbackEvent( AudioDeviceID deviceId,
+                      const AudioBufferList *inBufferList,
+                      const AudioBufferList *outBufferList );
+
+  private:
+
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
+  static const char* getErrorCode( OSStatus code );
+};
+
+#endif
+
+#if defined(__UNIX_JACK__)
+
+class RtApiJack: public RtApi
+{
+public:
+
+  RtApiJack();
+  ~RtApiJack();
+  RtAudio::Api getCurrentApi( void ) { return RtAudio::UNIX_JACK; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  void closeStream( void );
+  void startStream( void );
+  void stopStream( void );
+  void abortStream( void );
+  long getStreamLatency( void );
+
+  // This function is intended for internal use only.  It must be
+  // public because it is called by the internal callback handler,
+  // which is not a member of RtAudio.  External use of this function
+  // will most likely produce highly undesireable results!
+  bool callbackEvent( unsigned long nframes );
+
+  private:
+
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
+};
+
+#endif
+
+#if defined(__WINDOWS_ASIO__)
+
+class RtApiAsio: public RtApi
+{
+public:
+
+  RtApiAsio();
+  ~RtApiAsio();
+  RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_ASIO; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  void closeStream( void );
+  void startStream( void );
+  void stopStream( void );
+  void abortStream( void );
+  long getStreamLatency( void );
+
+  // This function is intended for internal use only.  It must be
+  // public because it is called by the internal callback handler,
+  // which is not a member of RtAudio.  External use of this function
+  // will most likely produce highly undesireable results!
+  bool callbackEvent( long bufferIndex );
+
+  private:
+
+  std::vector<RtAudio::DeviceInfo> devices_;
+  void saveDeviceInfo( void );
+  bool coInitialized_;
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
+};
+
+#endif
+
+#if defined(__WINDOWS_DS__)
+
+class RtApiDs: public RtApi
+{
+public:
+
+  RtApiDs();
+  ~RtApiDs();
+  RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_DS; }
+  unsigned int getDeviceCount( void );
+  unsigned int getDefaultOutputDevice( void );
+  unsigned int getDefaultInputDevice( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  void closeStream( void );
+  void startStream( void );
+  void stopStream( void );
+  void abortStream( void );
+  long getStreamLatency( void );
+
+  // This function is intended for internal use only.  It must be
+  // public because it is called by the internal callback handler,
+  // which is not a member of RtAudio.  External use of this function
+  // will most likely produce highly undesireable results!
+  void callbackEvent( void );
+
+  private:
+
+  bool coInitialized_;
+  bool buffersRolling;
+  long duplexPrerollBytes;
+  std::vector<struct DsDevice> dsDevices;
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
+};
+
+#endif
+
+#if defined(__WINDOWS_WASAPI__)
+
+struct IMMDeviceEnumerator;
+
+class RtApiWasapi : public RtApi
+{
+public:
+  RtApiWasapi();
+  ~RtApiWasapi();
+
+  RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_WASAPI; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  unsigned int getDefaultOutputDevice( void );
+  unsigned int getDefaultInputDevice( void );
+  void closeStream( void );
+  void startStream( void );
+  void stopStream( void );
+  void abortStream( void );
+
+private:
+  bool coInitialized_;
+  IMMDeviceEnumerator* deviceEnumerator_;
+
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int* bufferSize,
+                        RtAudio::StreamOptions* options );
+
+  static DWORD WINAPI runWasapiThread( void* wasapiPtr );
+  static DWORD WINAPI stopWasapiThread( void* wasapiPtr );
+  static DWORD WINAPI abortWasapiThread( void* wasapiPtr );
+  void wasapiThread();
+};
+
+#endif
+
+#if defined(__LINUX_ALSA__)
+
+class RtApiAlsa: public RtApi
+{
+public:
+
+  RtApiAlsa();
+  ~RtApiAlsa();
+  RtAudio::Api getCurrentApi() { return RtAudio::LINUX_ALSA; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  void closeStream( void );
+  void startStream( void );
+  void stopStream( void );
+  void abortStream( void );
+
+  // This function is intended for internal use only.  It must be
+  // public because it is called by the internal callback handler,
+  // which is not a member of RtAudio.  External use of this function
+  // will most likely produce highly undesireable results!
+  void callbackEvent( void );
+
+  private:
+
+  std::vector<RtAudio::DeviceInfo> devices_;
+  void saveDeviceInfo( void );
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
+};
+
+#endif
+
+#if defined(__LINUX_PULSE__)
+
+class RtApiPulse: public RtApi
+{
+public:
+  ~RtApiPulse();
+  RtAudio::Api getCurrentApi() { return RtAudio::LINUX_PULSE; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  void closeStream( void );
+  void startStream( void );
+  void stopStream( void );
+  void abortStream( void );
+
+  // This function is intended for internal use only.  It must be
+  // public because it is called by the internal callback handler,
+  // which is not a member of RtAudio.  External use of this function
+  // will most likely produce highly undesireable results!
+  void callbackEvent( void );
+
+  private:
+
+  std::vector<RtAudio::DeviceInfo> devices_;
+  void saveDeviceInfo( void );
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
+};
+
+#endif
+
+#if defined(__LINUX_OSS__)
+
+class RtApiOss: public RtApi
+{
+public:
+
+  RtApiOss();
+  ~RtApiOss();
+  RtAudio::Api getCurrentApi() { return RtAudio::LINUX_OSS; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  void closeStream( void );
+  void startStream( void );
+  void stopStream( void );
+  void abortStream( void );
+
+  // This function is intended for internal use only.  It must be
+  // public because it is called by the internal callback handler,
+  // which is not a member of RtAudio.  External use of this function
+  // will most likely produce highly undesireable results!
+  void callbackEvent( void );
+
+  private:
+
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
+};
+
+#endif
+
+#if defined(__RTAUDIO_DUMMY__)
+
+class RtApiDummy: public RtApi
+{
+public:
+
+  RtApiDummy() { errorText_ = "RtApiDummy: This class provides no functionality."; error( RtAudioError::WARNING ); }
+  RtAudio::Api getCurrentApi( void ) { return RtAudio::RTAUDIO_DUMMY; }
+  unsigned int getDeviceCount( void ) { return 0; }
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int /*device*/ ) { RtAudio::DeviceInfo info; return info; }
+  void closeStream( void ) {}
+  void startStream( void ) {}
+  void stopStream( void ) {}
+  void abortStream( void ) {}
+
+  private:
+
+  bool probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/, 
+                        unsigned int /*firstChannel*/, unsigned int /*sampleRate*/,
+                        RtAudioFormat /*format*/, unsigned int * /*bufferSize*/,
+                        RtAudio::StreamOptions * /*options*/ ) { return false; }
+};
+
+#endif
+
+#endif
+
+// Indentation settings for Vim and Emacs
+//
+// Local Variables:
+// c-basic-offset: 2
+// indent-tabs-mode: nil
+// End:
+//
+// vim: et sts=2 sw=2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/include/RtWvOut.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,96 @@
+#ifndef STK_RTWVOUT_H
+#define STK_RTWVOUT_H
+
+#include "WvOut.h"
+#include "RtAudio.h"
+#include "Mutex.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class RtWvOut
+    \brief STK realtime audio (blocking) output class.
+
+    This class provides a simplified interface to RtAudio for realtime
+    audio output.  It is a subclass of WvOut.  This class makes use of
+    RtAudio's callback functionality by creating a large ring-buffer
+    into which data is written.  This class should not be used when
+    low-latency is desired.
+
+    RtWvOut supports multi-channel data in interleaved format.  It is
+    important to distinguish the tick() method that outputs a single
+    sample to all channels in a sample frame from the overloaded one
+    that takes a reference to an StkFrames object for multi-channel
+    and/or multi-frame data.
+
+    by Perry R. Cook and Gary P. Scavone, 1995--2014.
+*/
+/***************************************************/
+
+class RtWvOut : public WvOut
+{
+ public:
+
+  //! Default constructor.
+  /*!
+    The default \e device argument value (zero) will select the
+    default output device on your system.  The first device enumerated
+    by the underlying audio API is specified with a value of one.  The
+    default buffer size of RT_BUFFER_SIZE is defined in Stk.h.  An
+    StkError will be thrown if an error occurs duing instantiation.
+  */
+  RtWvOut( unsigned int nChannels = 1, StkFloat sampleRate = Stk::sampleRate(),
+           int device = 0, int bufferFrames = RT_BUFFER_SIZE, int nBuffers = 20 );
+
+  //! Class destructor.
+  ~RtWvOut();
+
+  //! Start the audio output stream.
+  /*!
+    The stream is started automatically, if necessary, when a
+    tick() method is called.
+  */
+  void start( void );
+
+  //! Stop the audio output stream.
+  /*!
+    It may be necessary to use this method to avoid undesireable
+    audio buffer cycling if you wish to temporarily stop audio output.
+  */
+  void stop( void );
+
+  //! Output a single sample to all channels in a sample frame.
+  /*!
+    If the device is "stopped", it is "started".
+  */
+  void tick( const StkFloat sample );
+
+  //! Output the StkFrames data.
+  /*!
+    If the device is "stopped", it is "started".  The number of
+    channels in the StkFrames argument must equal the number of
+    channels specified during instantiation.  However, this is only
+    checked if _STK_DEBUG_ is defined during compilation, in which
+    case an incompatibility will trigger an StkError exception.
+  */
+  void tick( const StkFrames& frames );
+
+  // This function is not intended for general use but must be
+  // public for access from the audio callback function.
+  int readBuffer( void *buffer, unsigned int frameCount );
+
+ protected:
+
+  RtAudio dac_;
+  Mutex mutex_;
+  bool stopped_;
+  unsigned int readIndex_;
+  unsigned int writeIndex_;
+  long framesFilled_;
+  unsigned int status_; // running = 0, emptying buffer = 1, finished = 2
+
+};
+
+} // stk namespace
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/include/SineWave.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,159 @@
+#ifndef STK_SINEWAVE_H
+#define STK_SINEWAVE_H
+
+const unsigned long TABLE_SIZE = 2048;
+
+#include "Generator.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class SineWave
+    \brief STK sinusoid oscillator class.
+
+    This class computes and saves a static sine "table" that can be
+    shared by multiple instances.  It has an interface similar to the
+    WaveLoop class but inherits from the Generator class.  Output
+    values are computed using linear interpolation.
+
+    The "table" length, set in SineWave.h, is 2048 samples by default.
+
+    by Perry R. Cook and Gary P. Scavone, 1995--2014.
+*/
+/***************************************************/
+
+class SineWave : public Generator
+{
+public:
+  //! Default constructor.
+  SineWave( void );
+
+  //! Class destructor.
+  ~SineWave( void );
+
+  //! Clear output and reset time pointer to zero.
+  void reset( void );
+
+  //! Set the data read rate in samples.  The rate can be negative.
+  /*!
+    If the rate value is negative, the data is read in reverse order.
+  */
+  void setRate( StkFloat rate ) { rate_ = rate; };
+
+  //! Set the data interpolation rate based on a looping frequency.
+  /*!
+    This function determines the interpolation rate based on the file
+    size and the current Stk::sampleRate.  The \e frequency value
+    corresponds to file cycles per second.  The frequency can be
+    negative, in which case the loop is read in reverse order.
+   */
+  void setFrequency( StkFloat frequency );
+
+  //! Increment the read pointer by \e time in samples, modulo the table size.
+  void addTime( StkFloat time );
+
+  //! Increment the read pointer by a normalized \e phase value.
+  /*!
+    This function increments the read pointer by a normalized phase
+    value, such that \e phase = 1.0 corresponds to a 360 degree phase
+    shift.  Positive or negative values are possible.
+   */
+  void addPhase( StkFloat phase );
+
+  //! Add a normalized phase offset to the read pointer.
+  /*!
+    A \e phaseOffset = 1.0 corresponds to a 360 degree phase
+    offset.  Positive or negative values are possible.
+   */
+  void addPhaseOffset( StkFloat phaseOffset );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Compute and return one output sample.
+  StkFloat tick( void );
+
+  //! Fill a channel of the StkFrames object with computed outputs.
+  /*!
+    The \c channel argument must be less than the number of
+    channels in the StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+protected:
+
+  void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+
+  static StkFrames table_;
+  StkFloat time_;
+  StkFloat rate_;
+  StkFloat phaseOffset_;
+  unsigned int iIndex_;
+  StkFloat alpha_;
+
+};
+
+inline StkFloat SineWave :: tick( void )
+{
+  // Check limits of time address ... if necessary, recalculate modulo
+  // TABLE_SIZE.
+  while ( time_ < 0.0 )
+    time_ += TABLE_SIZE;
+  while ( time_ >= TABLE_SIZE )
+    time_ -= TABLE_SIZE;
+
+  iIndex_ = (unsigned int) time_;
+  alpha_ = time_ - iIndex_;
+  StkFloat tmp = table_[ iIndex_ ];
+  tmp += ( alpha_ * ( table_[ iIndex_ + 1 ] - tmp ) );
+
+  // Increment time, which can be negative.
+  time_ += rate_;
+
+  lastFrame_[0] = tmp;
+  return lastFrame_[0];
+}
+
+inline StkFrames& SineWave :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    oStream_ << "SineWave::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  StkFloat tmp = 0.0;
+
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+
+    // Check limits of time address ... if necessary, recalculate modulo
+    // TABLE_SIZE.
+    while ( time_ < 0.0 )
+      time_ += TABLE_SIZE;
+    while ( time_ >= TABLE_SIZE )
+      time_ -= TABLE_SIZE;
+
+    iIndex_ = (unsigned int) time_;
+    alpha_ = time_ - iIndex_;
+    tmp = table_[ iIndex_ ];
+    tmp += ( alpha_ * ( table_[ iIndex_ + 1 ] - tmp ) );
+    *samples = tmp;
+
+    // Increment time, which can be negative.
+    time_ += rate_;
+  }
+
+  lastFrame_[0] = tmp;
+  return frames;
+}
+
+} // stk namespace
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/include/Stk.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,548 @@
+#ifndef STK_STK_H
+#define STK_STK_H
+
+#include <string>
+#include <cstring>
+#include <iostream>
+#include <sstream>
+#include <vector>
+//#include <cstdlib>
+
+/*! \namespace stk
+    \brief The STK namespace.
+
+    Most Stk classes are defined within the STK namespace.  Exceptions
+    to this include the classes RtAudio and RtMidi.
+*/
+namespace stk {
+
+/***************************************************/
+/*! \class Stk
+    \brief STK base class
+
+    Nearly all STK classes inherit from this class.
+    The global sample rate and rawwave path variables
+    can be queried and modified via Stk.  In addition,
+    this class provides error handling and
+    byte-swapping functions.
+
+    The Synthesis ToolKit in C++ (STK) is a set of open source audio
+    signal processing and algorithmic synthesis classes written in the
+    C++ programming language. STK was designed to facilitate rapid
+    development of music synthesis and audio processing software, with
+    an emphasis on cross-platform functionality, realtime control,
+    ease of use, and educational example code.  STK currently runs
+    with realtime support (audio and MIDI) on Linux, Macintosh OS X,
+    and Windows computer platforms. Generic, non-realtime support has
+    been tested under NeXTStep, Sun, and other platforms and should
+    work with any standard C++ compiler.
+
+    STK WWW site: http://ccrma.stanford.edu/software/stk/
+
+    The Synthesis ToolKit in C++ (STK)
+    Copyright (c) 1995--2014 Perry R. Cook and Gary P. Scavone
+
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation files
+    (the "Software"), to deal in the Software without restriction,
+    including without limitation the rights to use, copy, modify, merge,
+    publish, distribute, sublicense, and/or sell copies of the Software,
+    and to permit persons to whom the Software is furnished to do so,
+    subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    Any person wishing to distribute modifications to the Software is
+    asked to send the modifications to the original developer so that
+    they can be incorporated into the canonical version.  This is,
+    however, not a binding provision of this license.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/***************************************************/
+
+//#define _STK_DEBUG_
+
+// Most data in STK is passed and calculated with the
+// following user-definable floating-point type.  You
+// can change this to "float" if you prefer or perhaps
+// a "long double" in the future.
+typedef double StkFloat;
+
+//! STK error handling class.
+/*!
+  This is a fairly abstract exception handling class.  There could
+  be sub-classes to take care of more specific error conditions ... or
+  not.
+*/
+class StkError
+{
+public:
+  enum Type {
+    STATUS,
+    WARNING,
+    DEBUG_PRINT,
+    MEMORY_ALLOCATION,
+    MEMORY_ACCESS,
+    FUNCTION_ARGUMENT,
+    FILE_NOT_FOUND,
+    FILE_UNKNOWN_FORMAT,
+    FILE_ERROR,
+    PROCESS_THREAD,
+    PROCESS_SOCKET,
+    PROCESS_SOCKET_IPADDR,
+    AUDIO_SYSTEM,
+    MIDI_SYSTEM,
+    UNSPECIFIED
+  };
+
+protected:
+  std::string message_;
+  Type type_;
+
+public:
+  //! The constructor.
+  StkError(const std::string& message, Type type = StkError::UNSPECIFIED)
+    : message_(message), type_(type) {}
+
+  //! The destructor.
+  virtual ~StkError(void) {};
+
+  //! Prints thrown error message to stderr.
+  virtual void printMessage(void) { std::cerr << '\n' << message_ << "\n\n"; }
+
+  //! Returns the thrown error message type.
+  virtual const Type& getType(void) { return type_; }
+
+  //! Returns the thrown error message string.
+  virtual const std::string& getMessage(void) { return message_; }
+
+  //! Returns the thrown error message as a C string.
+  virtual const char *getMessageCString(void) { return message_.c_str(); }
+};
+
+
+class Stk
+{
+public:
+
+  typedef unsigned long StkFormat;
+  static const StkFormat STK_SINT8;   /*!< -128 to +127 */
+  static const StkFormat STK_SINT16;  /*!< -32768 to +32767 */
+  static const StkFormat STK_SINT24;  /*!< Lower 3 bytes of 32-bit signed integer. */
+  static const StkFormat STK_SINT32;  /*!< -2147483648 to +2147483647. */
+  static const StkFormat STK_FLOAT32; /*!< Normalized between plus/minus 1.0. */
+  static const StkFormat STK_FLOAT64; /*!< Normalized between plus/minus 1.0. */
+
+  //! Static method that returns the current STK sample rate.
+  static StkFloat sampleRate( void ) { return srate_; }
+
+  //! Static method that sets the STK sample rate.
+  /*!
+    The sample rate set using this method is queried by all STK
+    classes that depend on its value.  It is initialized to the
+    default SRATE set in Stk.h.  Many STK classes use the sample rate
+    during instantiation.  Therefore, if you wish to use a rate that
+    is different from the default rate, it is imperative that it be
+    set \e BEFORE STK objects are instantiated.  A few classes that
+    make use of the global STK sample rate are automatically notified
+    when the rate changes so that internal class data can be
+    appropriately updated.  However, this has not been fully
+    implemented.  Specifically, classes that appropriately update
+    their own data when either a setFrequency() or noteOn() function
+    is called do not currently receive the automatic notification of
+    rate change.  If the user wants a specific class instance to
+    ignore such notifications, perhaps in a multi-rate context, the
+    function Stk::ignoreSampleRateChange() should be called.
+  */
+  static void setSampleRate( StkFloat rate );
+
+  //! A function to enable/disable the automatic updating of class data when the STK sample rate changes.
+  /*!
+    This function allows the user to enable or disable class data
+    updates in response to global sample rate changes on a class by
+    class basis.
+  */
+  void ignoreSampleRateChange( bool ignore = true ) { ignoreSampleRateChange_ = ignore; };
+
+  //! Static method that returns the current rawwave path.
+  static std::string rawwavePath(void) { return rawwavepath_; }
+
+  //! Static method that sets the STK rawwave path.
+  static void setRawwavePath( std::string path );
+
+  //! Static method that byte-swaps a 16-bit data type.
+  static void swap16( unsigned char *ptr );
+
+  //! Static method that byte-swaps a 32-bit data type.
+  static void swap32( unsigned char *ptr );
+
+  //! Static method that byte-swaps a 64-bit data type.
+  static void swap64( unsigned char *ptr );
+
+  //! Static cross-platform method to sleep for a number of milliseconds.
+  static void sleep( unsigned long milliseconds );
+
+  //! Static method to check whether a value is within a specified range.
+  static bool inRange( StkFloat value, StkFloat min, StkFloat max ) {
+    if ( value < min ) return false;
+    else if ( value > max ) return false;
+    else return true;
+  }
+
+  //! Static function for error reporting and handling using c-strings.
+  static void handleError( const char *message, StkError::Type type );
+
+  //! Static function for error reporting and handling using c++ strings.
+  static void handleError( std::string message, StkError::Type type );
+
+  //! Toggle display of WARNING and STATUS messages.
+  static void showWarnings( bool status ) { showWarnings_ = status; }
+
+  //! Toggle display of error messages before throwing exceptions.
+  static void printErrors( bool status ) { printErrors_ = status; }
+
+private:
+  static StkFloat srate_;
+  static std::string rawwavepath_;
+  static bool showWarnings_;
+  static bool printErrors_;
+  static std::vector<Stk *> alertList_;
+
+protected:
+
+  static std::ostringstream oStream_;
+  bool ignoreSampleRateChange_;
+
+  //! Default constructor.
+  Stk( void );
+
+  //! Class destructor.
+  virtual ~Stk( void );
+
+  //! This function should be implemented in subclasses that depend on the sample rate.
+  virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+
+  //! Add class pointer to list for sample rate change notification.
+  void addSampleRateAlert( Stk *ptr );
+
+  //! Remove class pointer from list for sample rate change notification.
+  void removeSampleRateAlert( Stk *ptr );
+
+  //! Internal function for error reporting that assumes message in \c oStream_ variable.
+  void handleError( StkError::Type type ) const;
+};
+
+
+/***************************************************/
+/*! \class StkFrames
+    \brief An STK class to handle vectorized audio data.
+
+    This class can hold single- or multi-channel audio data.  The data
+    type is always StkFloat and the channel format is always
+    interleaved.  In an effort to maintain efficiency, no
+    out-of-bounds checks are performed in this class unless
+    _STK_DEBUG_ is defined.
+
+    Internally, the data is stored in a one-dimensional C array.  An
+    indexing operator is available to set and retrieve data values.
+    Alternately, one can use pointers to access the data, using the
+    index operator to get an address for a particular location in the
+    data:
+
+      StkFloat* ptr = &myStkFrames[0];
+
+    Note that this class can also be used as a table with interpolating
+    lookup.
+
+    Possible future improvements in this class could include functions
+    to convert to and return other data types.
+
+    by Perry R. Cook and Gary P. Scavone, 1995--2014.
+*/
+/***************************************************/
+
+class StkFrames
+{
+public:
+
+  //! The default constructor initializes the frame data structure to size zero.
+  StkFrames( unsigned int nFrames = 0, unsigned int nChannels = 0 );
+
+  //! Overloaded constructor that initializes the frame data to the specified size with \c value.
+  StkFrames( const StkFloat& value, unsigned int nFrames, unsigned int nChannels );
+
+  //! The destructor.
+  ~StkFrames();
+
+  // A copy constructor.
+  StkFrames( const StkFrames& f );
+
+  // Assignment operator that returns a reference to self.
+  StkFrames& operator= ( const StkFrames& f );
+
+  //! Subscript operator that returns a reference to element \c n of self.
+  /*!
+    The result can be used as an lvalue. This reference is valid
+    until the resize function is called or the array is destroyed. The
+    index \c n must be between 0 and size less one.  No range checking
+    is performed unless _STK_DEBUG_ is defined.
+  */
+  StkFloat& operator[] ( size_t n );
+
+  //! Subscript operator that returns the value at element \c n of self.
+  /*!
+    The index \c n must be between 0 and size less one.  No range
+    checking is performed unless _STK_DEBUG_ is defined.
+  */
+  StkFloat operator[] ( size_t n ) const;
+
+  //! Assignment by sum operator into self.
+  /*!
+    The dimensions of the argument are expected to be the same as
+    self.  No range checking is performed unless _STK_DEBUG_ is
+    defined.
+  */
+  void operator+= ( StkFrames& f );
+
+  //! Assignment by product operator into self.
+  /*!
+    The dimensions of the argument are expected to be the same as
+    self.  No range checking is performed unless _STK_DEBUG_ is
+    defined.
+  */
+  void operator*= ( StkFrames& f );
+
+  //! Channel / frame subscript operator that returns a reference.
+  /*!
+    The result can be used as an lvalue. This reference is valid
+    until the resize function is called or the array is destroyed. The
+    \c frame index must be between 0 and frames() - 1.  The \c channel
+    index must be between 0 and channels() - 1.  No range checking is
+    performed unless _STK_DEBUG_ is defined.
+  */
+  StkFloat& operator() ( size_t frame, unsigned int channel );
+
+  //! Channel / frame subscript operator that returns a value.
+  /*!
+    The \c frame index must be between 0 and frames() - 1.  The \c
+    channel index must be between 0 and channels() - 1.  No range checking
+    is performed unless _STK_DEBUG_ is defined.
+  */
+  StkFloat operator() ( size_t frame, unsigned int channel ) const;
+
+  //! Return an interpolated value at the fractional frame index and channel.
+  /*!
+    This function performs linear interpolation.  The \c frame
+    index must be between 0.0 and frames() - 1.  The \c channel index
+    must be between 0 and channels() - 1.  No range checking is
+    performed unless _STK_DEBUG_ is defined.
+  */
+  StkFloat interpolate( StkFloat frame, unsigned int channel = 0 ) const;
+
+  //! Returns the total number of audio samples represented by the object.
+  size_t size() const { return size_; }; 
+
+  //! Returns \e true if the object size is zero and \e false otherwise.
+  bool empty() const;
+
+  //! Resize self to represent the specified number of channels and frames.
+  /*!
+    Changes the size of self based on the number of frames and
+    channels.  No element assignment is performed.  No memory
+    deallocation occurs if the new size is smaller than the previous
+    size.  Further, no new memory is allocated when the new size is
+    smaller or equal to a previously allocated size.
+  */
+  void resize( size_t nFrames, unsigned int nChannels = 1 );
+
+  //! Resize self to represent the specified number of channels and frames and perform element initialization.
+  /*!
+    Changes the size of self based on the number of frames and
+    channels, and assigns \c value to every element.  No memory
+    deallocation occurs if the new size is smaller than the previous
+    size.  Further, no new memory is allocated when the new size is
+    smaller or equal to a previously allocated size.
+  */
+  void resize( size_t nFrames, unsigned int nChannels, StkFloat value );
+
+  //! Return the number of channels represented by the data.
+  unsigned int channels( void ) const { return nChannels_; };
+
+  //! Return the number of sample frames represented by the data.
+  unsigned int frames( void ) const { return (unsigned int)nFrames_; };
+
+  //! Set the sample rate associated with the StkFrames data.
+  /*!
+    By default, this value is set equal to the current STK sample
+    rate at the time of instantiation.
+   */
+  void setDataRate( StkFloat rate ) { dataRate_ = rate; };
+
+  //! Return the sample rate associated with the StkFrames data.
+  /*!
+    By default, this value is set equal to the current STK sample
+    rate at the time of instantiation.
+   */
+  StkFloat dataRate( void ) const { return dataRate_; };
+
+private:
+
+  StkFloat *data_;
+  StkFloat dataRate_;
+  size_t nFrames_;
+  unsigned int nChannels_;
+  size_t size_;
+  size_t bufferSize_;
+
+};
+
+inline bool StkFrames :: empty() const
+{
+  if ( size_ > 0 ) return false;
+  else return true;
+}
+
+inline StkFloat& StkFrames :: operator[] ( size_t n )
+{
+#if defined(_STK_DEBUG_)
+  if ( n >= size_ ) {
+    std::ostringstream error;
+    error << "StkFrames::operator[]: invalid index (" << n << ") value!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  return data_[n];
+}
+
+inline StkFloat StkFrames :: operator[] ( size_t n ) const
+{
+#if defined(_STK_DEBUG_)
+  if ( n >= size_ ) {
+    std::ostringstream error;
+    error << "StkFrames::operator[]: invalid index (" << n << ") value!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  return data_[n];
+}
+
+inline StkFloat& StkFrames :: operator() ( size_t frame, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( frame >= nFrames_ || channel >= nChannels_ ) {
+    std::ostringstream error;
+    error << "StkFrames::operator(): invalid frame (" << frame << ") or channel (" << channel << ") value!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  return data_[ frame * nChannels_ + channel ];
+}
+
+inline StkFloat StkFrames :: operator() ( size_t frame, unsigned int channel ) const
+{
+#if defined(_STK_DEBUG_)
+  if ( frame >= nFrames_ || channel >= nChannels_ ) {
+    std::ostringstream error;
+    error << "StkFrames::operator(): invalid frame (" << frame << ") or channel (" << channel << ") value!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  return data_[ frame * nChannels_ + channel ];
+}
+
+inline void StkFrames :: operator+= ( StkFrames& f )
+{
+#if defined(_STK_DEBUG_)
+  if ( f.frames() != nFrames_ || f.channels() != nChannels_ ) {
+    std::ostringstream error;
+    error << "StkFrames::operator+=: frames argument must be of equal dimensions!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  StkFloat *fptr = &f[0];
+  StkFloat *dptr = data_;
+  for ( unsigned int i=0; i<size_; i++ )
+    *dptr++ += *fptr++;
+}
+
+inline void StkFrames :: operator*= ( StkFrames& f )
+{
+#if defined(_STK_DEBUG_)
+  if ( f.frames() != nFrames_ || f.channels() != nChannels_ ) {
+    std::ostringstream error;
+    error << "StkFrames::operator*=: frames argument must be of equal dimensions!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  StkFloat *fptr = &f[0];
+  StkFloat *dptr = data_;
+  for ( unsigned int i=0; i<size_; i++ )
+    *dptr++ *= *fptr++;
+}
+
+// Here are a few other useful typedefs.
+typedef unsigned short UINT16;
+typedef unsigned int UINT32;
+typedef signed short SINT16;
+typedef signed int SINT32;
+typedef float FLOAT32;
+typedef double FLOAT64;
+
+// The default sampling rate.
+const StkFloat SRATE = 44100.0;
+
+// The default real-time audio input and output buffer size.  If
+// clicks are occuring in the input and/or output sound stream, a
+// larger buffer size may help.  Larger buffer sizes, however, produce
+// more latency.
+const unsigned int RT_BUFFER_SIZE = 512;
+
+// The default rawwave path value is set with the preprocessor
+// definition RAWWAVE_PATH.  This can be specified as an argument to
+// the configure script, in an integrated development environment, or
+// below.  The global STK rawwave path variable can be dynamically set
+// with the Stk::setRawwavePath() function.  This value is
+// concatenated to the beginning of all references to rawwave files in
+// the various STK core classes (ex. Clarinet.cpp).  If you wish to
+// move the rawwaves directory to a different location in your file
+// system, you will need to set this path definition appropriately.
+#if !defined(RAWWAVE_PATH)
+  #define RAWWAVE_PATH "../../rawwaves/"
+#endif
+
+#ifndef PI
+const StkFloat PI           = 3.14159265358979;
+#endif
+const StkFloat TWO_PI       = 2 * PI;
+const StkFloat ONE_OVER_128 = 0.0078125;
+
+#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_MM__)
+  #define __OS_WINDOWS__
+  #define __STK_REALTIME__
+#elif defined(__LINUX_OSS__) || defined(__LINUX_ALSA__) || defined(__UNIX_JACK__)
+  #define __OS_LINUX__
+  #define __STK_REALTIME__
+#elif defined(__IRIX_AL__)
+  #define __OS_IRIX__
+#elif defined(__MACOSX_CORE__) || defined(__UNIX_JACK__)
+  #define __OS_MACOSX__
+  #define __STK_REALTIME__
+#endif
+
+} // stk namespace
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/include/WvOut.h	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,85 @@
+#ifndef STK_WVOUT_H
+#define STK_WVOUT_H
+
+#include "Stk.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class WvOut
+    \brief STK audio output abstract base class.
+
+    This class provides common functionality for a variety of audio
+    data output subclasses.
+
+    Currently, WvOut is non-interpolating and the output rate is
+    always Stk::sampleRate().
+
+    by Perry R. Cook and Gary P. Scavone, 1995--2014.
+*/
+/***************************************************/
+
+class WvOut : public Stk
+{
+ public:
+
+  //! Default constructor.
+  WvOut( void ) : frameCounter_(0), clipping_(false) {};
+
+  //! Return the number of sample frames output.
+  unsigned long getFrameCount( void ) const { return frameCounter_; };
+
+  //! Return the number of seconds of data output.
+  StkFloat getTime( void ) const { return (StkFloat) frameCounter_ / Stk::sampleRate(); };
+
+  //! Returns \c true if clipping has been detected during output since instantiation or the last reset.
+  bool clipStatus( void ) { return clipping_; };
+
+  //! Reset the clipping status to \c false.
+  void resetClipStatus( void ) { clipping_ = false; };
+
+  //! Output a single sample to all channels in a sample frame.
+  /*!
+    An StkError is thrown if an output error occurs.
+  */
+  virtual void tick( const StkFloat sample ) = 0;
+
+  //! Output the StkFrames data.
+  virtual void tick( const StkFrames& frames ) = 0;
+
+ protected:
+
+  // Check for sample clipping and clamp.
+  StkFloat& clipTest( StkFloat& sample );
+
+  StkFrames data_;
+  unsigned long frameCounter_;
+  bool clipping_;
+
+};
+
+inline StkFloat& WvOut :: clipTest( StkFloat& sample )
+{
+  bool clip = false;
+  if ( sample > 1.0 ) {
+    sample = 1.0;
+    clip = true;
+  }
+  else if ( sample < -1.0 ) {
+    sample = -1.0;
+    clip = true;
+  }
+
+  if ( clip == true && clipping_ == false ) {
+    // First occurrence of clipping since instantiation or reset.
+    clipping_ = true;
+    oStream_ << "WvOut: data value(s) outside +-1.0 detected ... clamping at outer bound!";
+    handleError( StkError::WARNING );
+  }
+
+  return sample;
+}
+
+} // stk namespace
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/src/ADSR.cpp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,180 @@
+/***************************************************/
+/*! \class ADSR
+    \brief STK ADSR envelope class.
+
+   This class implements a traditional ADSR (Attack, Decay, Sustain,
+    Release) envelope.  It responds to simple keyOn and keyOff
+    messages, keeping track of its state.  The \e state = ADSR::IDLE
+    before being triggered and after the envelope value reaches 0.0 in
+    the ADSR::RELEASE state.  All rate, target and level settings must
+    be non-negative.  All time settings must be positive.
+
+    by Perry R. Cook and Gary P. Scavone, 1995--2014.
+*/
+/***************************************************/
+
+#include "../include/ADSR.h"
+
+namespace stk {
+
+ADSR :: ADSR( void )
+{
+  target_ = 0.0;
+  value_ = 0.0;
+  attackRate_ = 0.001;
+  decayRate_ = 0.001;
+  releaseRate_ = 0.005;
+  releaseTime_ = -1.0;
+  sustainLevel_ = 0.5;
+  state_ = IDLE;
+  Stk::addSampleRateAlert( this );
+}
+
+ADSR :: ~ADSR( void )
+{
+}
+
+void ADSR :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  if ( !ignoreSampleRateChange_ ) {
+    attackRate_ = oldRate * attackRate_ / newRate;
+    decayRate_ = oldRate * decayRate_ / newRate;
+    releaseRate_ = oldRate * releaseRate_ / newRate;
+  }
+}
+
+void ADSR :: keyOn()
+{
+  if ( target_ <= 0.0 ) target_ = 1.0;
+  state_ = ATTACK;
+}
+
+void ADSR :: keyOff()
+{
+  target_ = 0.0;
+  state_ = RELEASE;
+
+  // FIXED October 2010 - Nick Donaldson
+  // Need to make release rate relative to current value!!
+  // Only update if we have set a TIME rather than a RATE,
+  // in which case releaseTime_ will be -1
+  if ( releaseTime_ > 0.0 )
+	  releaseRate_ = value_ / ( releaseTime_ * Stk::sampleRate() );
+}
+
+void ADSR :: setAttackRate( StkFloat rate )
+{
+  if ( rate < 0.0 ) {
+    oStream_ << "ADSR::setAttackRate: argument must be >= 0.0!";
+    handleError( StkError::WARNING ); return;
+  }
+
+  attackRate_ = rate;
+}
+
+void ADSR :: setAttackTarget( StkFloat target )
+{
+  if ( target < 0.0 ) {
+    oStream_ << "ADSR::setAttackTarget: negative target not allowed!";
+    handleError( StkError::WARNING ); return;
+  }
+
+  target_ = target;
+}
+
+void ADSR :: setDecayRate( StkFloat rate )
+{
+  if ( rate < 0.0 ) {
+    oStream_ << "ADSR::setDecayRate: negative rates not allowed!";
+    handleError( StkError::WARNING ); return;
+  }
+
+  decayRate_ = rate;
+}
+
+void ADSR :: setSustainLevel( StkFloat level )
+{
+  if ( level < 0.0 ) {
+    oStream_ << "ADSR::setSustainLevel: negative level not allowed!";
+    handleError( StkError::WARNING ); return;
+  }
+
+  sustainLevel_ = level;
+}
+
+void ADSR :: setReleaseRate( StkFloat rate )
+{
+  if ( rate < 0.0 ) {
+    oStream_ << "ADSR::setReleaseRate: negative rates not allowed!";
+    handleError( StkError::WARNING ); return;
+  }
+
+  releaseRate_ = rate;
+
+  // Set to negative value so we don't update the release rate on keyOff()
+  releaseTime_ = -1.0;
+}
+
+void ADSR :: setAttackTime( StkFloat time )
+{
+  if ( time <= 0.0 ) {
+    oStream_ << "ADSR::setAttackTime: negative or zero times not allowed!";
+    handleError( StkError::WARNING ); return;
+  }
+
+  attackRate_ = 1.0 / ( time * Stk::sampleRate() );
+}
+
+void ADSR :: setDecayTime( StkFloat time )
+{
+  if ( time <= 0.0 ) {
+    oStream_ << "ADSR::setDecayTime: negative or zero times not allowed!";
+    handleError( StkError::WARNING ); return;
+  }
+
+  decayRate_ = (1.0 - sustainLevel_) / ( time * Stk::sampleRate() );
+}
+
+void ADSR :: setReleaseTime( StkFloat time )
+{
+  if ( time <= 0.0 ) {
+    oStream_ << "ADSR::setReleaseTime: negative or zero times not allowed!";
+    handleError( StkError::WARNING ); return;
+  }
+
+  releaseRate_ = sustainLevel_ / ( time * Stk::sampleRate() );
+  releaseTime_ = time;
+}
+
+void ADSR :: setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime )
+{
+  this->setAttackTime( aTime );
+  this->setSustainLevel( sLevel );
+  this->setDecayTime( dTime );
+  this->setReleaseTime( rTime );
+}
+
+void ADSR :: setTarget( StkFloat target )
+{
+  if ( target < 0.0 ) {
+    oStream_ << "ADSR::setTarget: negative target not allowed!";
+    handleError( StkError::WARNING ); return;
+  }
+
+  target_ = target;
+
+  this->setSustainLevel( target_ );
+  if ( value_ < target_ ) state_ = ATTACK;
+  if ( value_ > target_ ) state_ = DECAY;
+}
+
+void ADSR :: setValue( StkFloat value )
+{
+  state_ = SUSTAIN;
+  target_ = value;
+  value_ = value;
+  this->setSustainLevel( value );
+  lastFrame_[0] = value;
+}
+
+} // stk namespace
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/src/Envelope.cpp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,84 @@
+/***************************************************/
+/*! \class Envelope
+    \brief STK linear line envelope class.
+
+    This class implements a simple linear line envelope generator
+    which is capable of ramping to an arbitrary target value by a
+    specified \e rate.  It also responds to simple \e keyOn and \e
+    keyOff messages, ramping to 1.0 on keyOn and to 0.0 on keyOff.
+
+    by Perry R. Cook and Gary P. Scavone, 1995--2014.
+*/
+/***************************************************/
+
+#include "../include/Envelope.h"
+
+namespace stk {
+
+Envelope :: Envelope( void ) : Generator()
+{    
+  target_ = 0.0;
+  value_ = 0.0;
+  rate_ = 0.001;
+  state_ = 0;
+  Stk::addSampleRateAlert( this );
+}
+
+Envelope :: ~Envelope( void )
+{
+  Stk::removeSampleRateAlert( this );
+}
+
+Envelope& Envelope :: operator= ( const Envelope& e )
+{
+  if ( this != &e ) {
+    target_ = e.target_;
+    value_ = e.value_;
+    rate_ = e.rate_;
+    state_ = e.state_;
+  }
+
+  return *this;
+}
+
+void Envelope :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  if ( !ignoreSampleRateChange_ )
+    rate_ = oldRate * rate_ / newRate;
+}
+
+void Envelope :: setRate( StkFloat rate )
+{
+  if ( rate < 0.0 ) {
+    oStream_ << "Envelope::setRate: argument must be >= 0.0!";
+    handleError( StkError::WARNING ); return;
+  }
+
+  rate_ = rate;
+}
+
+void Envelope :: setTime( StkFloat time )
+{
+  if ( time <= 0.0 ) {
+    oStream_ << "Envelope::setTime: argument must be > 0.0!";
+    handleError( StkError::WARNING ); return;
+  }
+
+  rate_ = 1.0 / ( time * Stk::sampleRate() );
+}
+
+void Envelope :: setTarget( StkFloat target )
+{
+  target_ = target;
+  if ( value_ != target_ ) state_ = 1;
+}
+
+void Envelope :: setValue( StkFloat value )
+{
+  state_ = 0;
+  target_ = value;
+  value_ = value;
+  lastFrame_[0] = value_;
+}
+
+} // stk namespace
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/src/Mutex.cpp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,105 @@
+/***************************************************/
+/*! \class Mutex
+    \brief STK mutex class.
+
+    This class provides a uniform interface for
+    cross-platform mutex use.  On Linux and IRIX
+    systems, the pthread library is used. Under
+    Windows, critical sections are used.
+
+    by Perry R. Cook and Gary P. Scavone, 1995--2014.
+*/
+/***************************************************/
+#pragma once
+
+#include "../include/Mutex.h"
+
+namespace stk {
+
+Mutex :: Mutex()
+{
+
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  pthread_mutex_init(&mutex_, NULL);
+  pthread_cond_init(&condition_, NULL);
+
+#elif defined(__OS_WINDOWS__)
+
+  InitializeCriticalSection(&mutex_);
+  condition_ = CreateEvent(NULL,  // no security
+                           true,  // manual-reset
+                           false, // non-signaled initially
+                           NULL); // unnamed
+
+#endif 
+}
+
+Mutex :: ~Mutex()
+{
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  pthread_mutex_destroy(&mutex_);
+  pthread_cond_destroy(&condition_);
+
+#elif defined(__OS_WINDOWS__)
+
+  DeleteCriticalSection(&mutex_);
+  CloseHandle( condition_ );
+
+#endif 
+}
+
+void Mutex :: lock()
+{
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  pthread_mutex_lock(&mutex_);
+
+#elif defined(__OS_WINDOWS__)
+
+  EnterCriticalSection(&mutex_);
+
+#endif 
+}
+
+void Mutex :: unlock()
+{
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  pthread_mutex_unlock(&mutex_);
+
+#elif defined(__OS_WINDOWS__)
+
+  LeaveCriticalSection(&mutex_);
+
+#endif 
+}
+
+void Mutex :: wait()
+{
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  pthread_cond_wait(&condition_, &mutex_);
+
+#elif defined(__OS_WINDOWS__)
+
+  WaitForMultipleObjects(1, &condition_, false, INFINITE);
+
+#endif 
+}
+
+void Mutex :: signal()
+{
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  pthread_cond_signal(&condition_);
+
+#elif defined(__OS_WINDOWS__)
+
+  SetEvent( condition_ );
+
+#endif 
+}
+
+} // stk namespace
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/src/RtAudio.cpp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,10142 @@
+/************************************************************************/
+/*! \class RtAudio
+    \brief Realtime audio i/o C++ classes.
+
+    RtAudio provides a common API (Application Programming Interface)
+    for realtime audio input/output across Linux (native ALSA, Jack,
+    and OSS), Macintosh OS X (CoreAudio and Jack), and Windows
+    (DirectSound, ASIO and WASAPI) operating systems.
+
+    RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
+
+    RtAudio: realtime audio i/o C++ classes
+    Copyright (c) 2001-2014 Gary P. Scavone
+
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation files
+    (the "Software"), to deal in the Software without restriction,
+    including without limitation the rights to use, copy, modify, merge,
+    publish, distribute, sublicense, and/or sell copies of the Software,
+    and to permit persons to whom the Software is furnished to do so,
+    subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    Any person wishing to distribute modifications to the Software is
+    asked to send the modifications to the original developer so that
+    they can be incorporated into the canonical version.  This is,
+    however, not a binding provision of this license.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/************************************************************************/
+
+// RtAudio: Version 4.1.1
+#pragma once
+
+
+#include "../include/RtAudio.h"
+#include <iostream>
+#include <cstdlib>
+#include <cstring>
+#include <climits>
+
+template <class T> const T& max(const T& a, const T& b) {
+	return (a<b) ? b : a;     // or: return comp(a,b)?b:a; for version (2)
+}
+
+// Static variable definitions.
+const unsigned int RtApi::MAX_SAMPLE_RATES = 14;
+const unsigned int RtApi::SAMPLE_RATES[] = {
+  4000, 5512, 8000, 9600, 11025, 16000, 22050,
+  32000, 44100, 48000, 88200, 96000, 176400, 192000
+};
+
+#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_WASAPI__)
+  #define MUTEX_INITIALIZE(A) InitializeCriticalSection(A)
+  #define MUTEX_DESTROY(A)    DeleteCriticalSection(A)
+  #define MUTEX_LOCK(A)       EnterCriticalSection(A)
+  #define MUTEX_UNLOCK(A)     LeaveCriticalSection(A)
+#elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
+  // pthread API
+  #define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL)
+  #define MUTEX_DESTROY(A)    pthread_mutex_destroy(A)
+  #define MUTEX_LOCK(A)       pthread_mutex_lock(A)
+  #define MUTEX_UNLOCK(A)     pthread_mutex_unlock(A)
+#else
+  #define MUTEX_INITIALIZE(A) abs(*A) // dummy definitions
+  #define MUTEX_DESTROY(A)    abs(*A) // dummy definitions
+#endif
+
+// *************************************************** //
+//
+// RtAudio definitions.
+//
+// *************************************************** //
+
+std::string RtAudio :: getVersion( void ) throw()
+{
+  return RTAUDIO_VERSION;
+}
+
+void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis ) throw()
+{
+  apis.clear();
+
+  // The order here will control the order of RtAudio's API search in
+  // the constructor.
+#if defined(__UNIX_JACK__)
+  apis.push_back( UNIX_JACK );
+#endif
+#if defined(__LINUX_ALSA__)
+  apis.push_back( LINUX_ALSA );
+#endif
+#if defined(__LINUX_PULSE__)
+  apis.push_back( LINUX_PULSE );
+#endif
+#if defined(__LINUX_OSS__)
+  apis.push_back( LINUX_OSS );
+#endif
+#if defined(__WINDOWS_ASIO__)
+  apis.push_back( WINDOWS_ASIO );
+#endif
+#if defined(__WINDOWS_WASAPI__)
+  apis.push_back( WINDOWS_WASAPI );
+#endif
+#if defined(__WINDOWS_DS__)
+  apis.push_back( WINDOWS_DS );
+#endif
+#if defined(__MACOSX_CORE__)
+  apis.push_back( MACOSX_CORE );
+#endif
+#if defined(__RTAUDIO_DUMMY__)
+  apis.push_back( RTAUDIO_DUMMY );
+#endif
+}
+
+void RtAudio :: openRtApi( RtAudio::Api api )
+{
+  if ( rtapi_ )
+    delete rtapi_;
+  rtapi_ = 0;
+
+#if defined(__UNIX_JACK__)
+  if ( api == UNIX_JACK )
+    rtapi_ = new RtApiJack();
+#endif
+#if defined(__LINUX_ALSA__)
+  if ( api == LINUX_ALSA )
+    rtapi_ = new RtApiAlsa();
+#endif
+#if defined(__LINUX_PULSE__)
+  if ( api == LINUX_PULSE )
+    rtapi_ = new RtApiPulse();
+#endif
+#if defined(__LINUX_OSS__)
+  if ( api == LINUX_OSS )
+    rtapi_ = new RtApiOss();
+#endif
+#if defined(__WINDOWS_ASIO__)
+  if ( api == WINDOWS_ASIO )
+    rtapi_ = new RtApiAsio();
+#endif
+#if defined(__WINDOWS_WASAPI__)
+  if ( api == WINDOWS_WASAPI )
+    rtapi_ = new RtApiWasapi();
+#endif
+#if defined(__WINDOWS_DS__)
+  if ( api == WINDOWS_DS )
+    rtapi_ = new RtApiDs();
+#endif
+#if defined(__MACOSX_CORE__)
+  if ( api == MACOSX_CORE )
+    rtapi_ = new RtApiCore();
+#endif
+#if defined(__RTAUDIO_DUMMY__)
+  if ( api == RTAUDIO_DUMMY )
+    rtapi_ = new RtApiDummy();
+#endif
+}
+
+RtAudio :: RtAudio( RtAudio::Api api )
+{
+  rtapi_ = 0;
+
+  if ( api != UNSPECIFIED ) {
+    // Attempt to open the specified API.
+    openRtApi( api );
+    if ( rtapi_ ) return;
+
+    // No compiled support for specified API value.  Issue a debug
+    // warning and continue as if no API was specified.
+    std::cerr << "\nRtAudio: no compiled support for specified API argument!\n" << std::endl;
+  }
+
+  // Iterate through the compiled APIs and return as soon as we find
+  // one with at least one device or we reach the end of the list.
+  std::vector< RtAudio::Api > apis;
+  getCompiledApi( apis );
+  for ( unsigned int i=0; i<apis.size(); i++ ) {
+    openRtApi( apis[i] );
+    if ( rtapi_->getDeviceCount() ) break;
+  }
+
+  if ( rtapi_ ) return;
+
+  // It should not be possible to get here because the preprocessor
+  // definition __RTAUDIO_DUMMY__ is automatically defined if no
+  // API-specific definitions are passed to the compiler. But just in
+  // case something weird happens, we'll thow an error.
+  std::string errorText = "\nRtAudio: no compiled API support found ... critical error!!\n\n";
+  throw( RtAudioError( errorText, RtAudioError::UNSPECIFIED ) );
+}
+
+RtAudio :: ~RtAudio() throw()
+{
+  if ( rtapi_ )
+    delete rtapi_;
+}
+
+void RtAudio :: openStream( RtAudio::StreamParameters *outputParameters,
+                            RtAudio::StreamParameters *inputParameters,
+                            RtAudioFormat format, unsigned int sampleRate,
+                            unsigned int *bufferFrames,
+                            RtAudioCallback callback, void *userData,
+                            RtAudio::StreamOptions *options,
+                            RtAudioErrorCallback errorCallback )
+{
+  return rtapi_->openStream( outputParameters, inputParameters, format,
+                             sampleRate, bufferFrames, callback,
+                             userData, options, errorCallback );
+}
+
+// *************************************************** //
+//
+// Public RtApi definitions (see end of file for
+// private or protected utility functions).
+//
+// *************************************************** //
+
+RtApi :: RtApi()
+{
+  stream_.state = STREAM_CLOSED;
+  stream_.mode = UNINITIALIZED;
+  stream_.apiHandle = 0;
+  stream_.userBuffer[0] = 0;
+  stream_.userBuffer[1] = 0;
+  MUTEX_INITIALIZE( &stream_.mutex );
+  showWarnings_ = true;
+  firstErrorOccurred_ = false;
+}
+
+RtApi :: ~RtApi()
+{
+  MUTEX_DESTROY( &stream_.mutex );
+}
+
+void RtApi :: openStream( RtAudio::StreamParameters *oParams,
+                          RtAudio::StreamParameters *iParams,
+                          RtAudioFormat format, unsigned int sampleRate,
+                          unsigned int *bufferFrames,
+                          RtAudioCallback callback, void *userData,
+                          RtAudio::StreamOptions *options,
+                          RtAudioErrorCallback errorCallback )
+{
+  if ( stream_.state != STREAM_CLOSED ) {
+    errorText_ = "RtApi::openStream: a stream is already open!";
+    error( RtAudioError::INVALID_USE );
+    return;
+  }
+
+  // Clear stream information potentially left from a previously open stream.
+  clearStreamInfo();
+
+  if ( oParams && oParams->nChannels < 1 ) {
+    errorText_ = "RtApi::openStream: a non-NULL output StreamParameters structure cannot have an nChannels value less than one.";
+    error( RtAudioError::INVALID_USE );
+    return;
+  }
+
+  if ( iParams && iParams->nChannels < 1 ) {
+    errorText_ = "RtApi::openStream: a non-NULL input StreamParameters structure cannot have an nChannels value less than one.";
+    error( RtAudioError::INVALID_USE );
+    return;
+  }
+
+  if ( oParams == NULL && iParams == NULL ) {
+    errorText_ = "RtApi::openStream: input and output StreamParameters structures are both NULL!";
+    error( RtAudioError::INVALID_USE );
+    return;
+  }
+
+  if ( formatBytes(format) == 0 ) {
+    errorText_ = "RtApi::openStream: 'format' parameter value is undefined.";
+    error( RtAudioError::INVALID_USE );
+    return;
+  }
+
+  unsigned int nDevices = getDeviceCount();
+  unsigned int oChannels = 0;
+  if ( oParams ) {
+    oChannels = oParams->nChannels;
+    if ( oParams->deviceId >= nDevices ) {
+      errorText_ = "RtApi::openStream: output device parameter value is invalid.";
+      error( RtAudioError::INVALID_USE );
+      return;
+    }
+  }
+
+  unsigned int iChannels = 0;
+  if ( iParams ) {
+    iChannels = iParams->nChannels;
+    if ( iParams->deviceId >= nDevices ) {
+      errorText_ = "RtApi::openStream: input device parameter value is invalid.";
+      error( RtAudioError::INVALID_USE );
+      return;
+    }
+  }
+
+  bool result;
+
+  if ( oChannels > 0 ) {
+
+    result = probeDeviceOpen( oParams->deviceId, OUTPUT, oChannels, oParams->firstChannel,
+                              sampleRate, format, bufferFrames, options );
+    if ( result == false ) {
+      error( RtAudioError::SYSTEM_ERROR );
+      return;
+    }
+  }
+
+  if ( iChannels > 0 ) {
+
+    result = probeDeviceOpen( iParams->deviceId, INPUT, iChannels, iParams->firstChannel,
+                              sampleRate, format, bufferFrames, options );
+    if ( result == false ) {
+      if ( oChannels > 0 ) closeStream();
+      error( RtAudioError::SYSTEM_ERROR );
+      return;
+    }
+  }
+
+  stream_.callbackInfo.callback = (void *) callback;
+  stream_.callbackInfo.userData = userData;
+  stream_.callbackInfo.errorCallback = (void *) errorCallback;
+
+  if ( options ) options->numberOfBuffers = stream_.nBuffers;
+  stream_.state = STREAM_STOPPED;
+}
+
+unsigned int RtApi :: getDefaultInputDevice( void )
+{
+  // Should be implemented in subclasses if possible.
+  return 0;
+}
+
+unsigned int RtApi :: getDefaultOutputDevice( void )
+{
+  // Should be implemented in subclasses if possible.
+  return 0;
+}
+
+void RtApi :: closeStream( void )
+{
+  // MUST be implemented in subclasses!
+  return;
+}
+
+bool RtApi :: probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/,
+                               unsigned int /*firstChannel*/, unsigned int /*sampleRate*/,
+                               RtAudioFormat /*format*/, unsigned int * /*bufferSize*/,
+                               RtAudio::StreamOptions * /*options*/ )
+{
+  // MUST be implemented in subclasses!
+  return FAILURE;
+}
+
+void RtApi :: tickStreamTime( void )
+{
+  // Subclasses that do not provide their own implementation of
+  // getStreamTime should call this function once per buffer I/O to
+  // provide basic stream time support.
+
+  stream_.streamTime += ( stream_.bufferSize * 1.0 / stream_.sampleRate );
+
+#if defined( HAVE_GETTIMEOFDAY )
+  gettimeofday( &stream_.lastTickTimestamp, NULL );
+#endif
+}
+
+long RtApi :: getStreamLatency( void )
+{
+  verifyStream();
+
+  long totalLatency = 0;
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX )
+    totalLatency = stream_.latency[0];
+  if ( stream_.mode == INPUT || stream_.mode == DUPLEX )
+    totalLatency += stream_.latency[1];
+
+  return totalLatency;
+}
+
+double RtApi :: getStreamTime( void )
+{
+  verifyStream();
+
+#if defined( HAVE_GETTIMEOFDAY )
+  // Return a very accurate estimate of the stream time by
+  // adding in the elapsed time since the last tick.
+  struct timeval then;
+  struct timeval now;
+
+  if ( stream_.state != STREAM_RUNNING || stream_.streamTime == 0.0 )
+    return stream_.streamTime;
+
+  gettimeofday( &now, NULL );
+  then = stream_.lastTickTimestamp;
+  return stream_.streamTime +
+    ((now.tv_sec + 0.000001 * now.tv_usec) -
+     (then.tv_sec + 0.000001 * then.tv_usec));     
+#else
+  return stream_.streamTime;
+#endif
+}
+
+void RtApi :: setStreamTime( double time )
+{
+  verifyStream();
+
+  if ( time >= 0.0 )
+    stream_.streamTime = time;
+}
+
+unsigned int RtApi :: getStreamSampleRate( void )
+{
+ verifyStream();
+
+ return stream_.sampleRate;
+}
+
+
+// *************************************************** //
+//
+// OS/API-specific methods.
+//
+// *************************************************** //
+
+#if defined(__MACOSX_CORE__)
+
+// The OS X CoreAudio API is designed to use a separate callback
+// procedure for each of its audio devices.  A single RtAudio duplex
+// stream using two different devices is supported here, though it
+// cannot be guaranteed to always behave correctly because we cannot
+// synchronize these two callbacks.
+//
+// A property listener is installed for over/underrun information.
+// However, no functionality is currently provided to allow property
+// listeners to trigger user handlers because it is unclear what could
+// be done if a critical stream parameter (buffer size, sample rate,
+// device disconnect) notification arrived.  The listeners entail
+// quite a bit of extra code and most likely, a user program wouldn't
+// be prepared for the result anyway.  However, we do provide a flag
+// to the client callback function to inform of an over/underrun.
+
+// A structure to hold various information related to the CoreAudio API
+// implementation.
+struct CoreHandle {
+  AudioDeviceID id[2];    // device ids
+#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
+  AudioDeviceIOProcID procId[2];
+#endif
+  UInt32 iStream[2];      // device stream index (or first if using multiple)
+  UInt32 nStreams[2];     // number of streams to use
+  bool xrun[2];
+  char *deviceBuffer;
+  pthread_cond_t condition;
+  int drainCounter;       // Tracks callback counts when draining
+  bool internalDrain;     // Indicates if stop is initiated from callback or not.
+
+  CoreHandle()
+    :deviceBuffer(0), drainCounter(0), internalDrain(false) { nStreams[0] = 1; nStreams[1] = 1; id[0] = 0; id[1] = 0; xrun[0] = false; xrun[1] = false; }
+};
+
+RtApiCore:: RtApiCore()
+{
+#if defined( AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER )
+  // This is a largely undocumented but absolutely necessary
+  // requirement starting with OS-X 10.6.  If not called, queries and
+  // updates to various audio device properties are not handled
+  // correctly.
+  CFRunLoopRef theRunLoop = NULL;
+  AudioObjectPropertyAddress property = { kAudioHardwarePropertyRunLoop,
+                                          kAudioObjectPropertyScopeGlobal,
+                                          kAudioObjectPropertyElementMaster };
+  OSStatus result = AudioObjectSetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop);
+  if ( result != noErr ) {
+    errorText_ = "RtApiCore::RtApiCore: error setting run loop property!";
+    error( RtAudioError::WARNING );
+  }
+#endif
+}
+
+RtApiCore :: ~RtApiCore()
+{
+  // The subclass destructor gets called before the base class
+  // destructor, so close an existing stream before deallocating
+  // apiDeviceId memory.
+  if ( stream_.state != STREAM_CLOSED ) closeStream();
+}
+
+unsigned int RtApiCore :: getDeviceCount( void )
+{
+  // Find out how many audio devices there are, if any.
+  UInt32 dataSize;
+  AudioObjectPropertyAddress propertyAddress = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
+  OSStatus result = AudioObjectGetPropertyDataSize( kAudioObjectSystemObject, &propertyAddress, 0, NULL, &dataSize );
+  if ( result != noErr ) {
+    errorText_ = "RtApiCore::getDeviceCount: OS-X error getting device info!";
+    error( RtAudioError::WARNING );
+    return 0;
+  }
+
+  return dataSize / sizeof( AudioDeviceID );
+}
+
+unsigned int RtApiCore :: getDefaultInputDevice( void )
+{
+  unsigned int nDevices = getDeviceCount();
+  if ( nDevices <= 1 ) return 0;
+
+  AudioDeviceID id;
+  UInt32 dataSize = sizeof( AudioDeviceID );
+  AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
+  OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, &dataSize, &id );
+  if ( result != noErr ) {
+    errorText_ = "RtApiCore::getDefaultInputDevice: OS-X system error getting device.";
+    error( RtAudioError::WARNING );
+    return 0;
+  }
+
+  dataSize *= nDevices;
+  AudioDeviceID deviceList[ nDevices ];
+  property.mSelector = kAudioHardwarePropertyDevices;
+  result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, &dataSize, (void *) &deviceList );
+  if ( result != noErr ) {
+    errorText_ = "RtApiCore::getDefaultInputDevice: OS-X system error getting device IDs.";
+    error( RtAudioError::WARNING );
+    return 0;
+  }
+
+  for ( unsigned int i=0; i<nDevices; i++ )
+    if ( id == deviceList[i] ) return i;
+
+  errorText_ = "RtApiCore::getDefaultInputDevice: No default device found!";
+  error( RtAudioError::WARNING );
+  return 0;
+}
+
+unsigned int RtApiCore :: getDefaultOutputDevice( void )
+{
+  unsigned int nDevices = getDeviceCount();
+  if ( nDevices <= 1 ) return 0;
+
+  AudioDeviceID id;
+  UInt32 dataSize = sizeof( AudioDeviceID );
+  AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
+  OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, &dataSize, &id );
+  if ( result != noErr ) {
+    errorText_ = "RtApiCore::getDefaultOutputDevice: OS-X system error getting device.";
+    error( RtAudioError::WARNING );
+    return 0;
+  }
+
+  dataSize = sizeof( AudioDeviceID ) * nDevices;
+  AudioDeviceID deviceList[ nDevices ];
+  property.mSelector = kAudioHardwarePropertyDevices;
+  result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, &dataSize, (void *) &deviceList );
+  if ( result != noErr ) {
+    errorText_ = "RtApiCore::getDefaultOutputDevice: OS-X system error getting device IDs.";
+    error( RtAudioError::WARNING );
+    return 0;
+  }
+
+  for ( unsigned int i=0; i<nDevices; i++ )
+    if ( id == deviceList[i] ) return i;
+
+  errorText_ = "RtApiCore::getDefaultOutputDevice: No default device found!";
+  error( RtAudioError::WARNING );
+  return 0;
+}
+
+RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device )
+{
+  RtAudio::DeviceInfo info;
+  info.probed = false;
+
+  // Get device ID
+  unsigned int nDevices = getDeviceCount();
+  if ( nDevices == 0 ) {
+    errorText_ = "RtApiCore::getDeviceInfo: no devices found!";
+    error( RtAudioError::INVALID_USE );
+    return info;
+  }
+
+  if ( device >= nDevices ) {
+    errorText_ = "RtApiCore::getDeviceInfo: device ID is invalid!";
+    error( RtAudioError::INVALID_USE );
+    return info;
+  }
+
+  AudioDeviceID deviceList[ nDevices ];
+  UInt32 dataSize = sizeof( AudioDeviceID ) * nDevices;
+  AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
+                                          kAudioObjectPropertyScopeGlobal,
+                                          kAudioObjectPropertyElementMaster };
+  OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property,
+                                                0, NULL, &dataSize, (void *) &deviceList );
+  if ( result != noErr ) {
+    errorText_ = "RtApiCore::getDeviceInfo: OS-X system error getting device IDs.";
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  AudioDeviceID id = deviceList[ device ];
+
+  // Get the device name.
+  info.name.erase();
+  CFStringRef cfname;
+  dataSize = sizeof( CFStringRef );
+  property.mSelector = kAudioObjectPropertyManufacturer;
+  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &cfname );
+  if ( result != noErr ) {
+    errorStream_ << "RtApiCore::probeDeviceInfo: system error (" << getErrorCode( result ) << ") getting device manufacturer.";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  //const char *mname = CFStringGetCStringPtr( cfname, CFStringGetSystemEncoding() );
+  int length = CFStringGetLength(cfname);
+  char *mname = (char *)malloc(length * 3 + 1);
+#if defined( UNICODE ) || defined( _UNICODE )
+  CFStringGetCString(cfname, mname, length * 3 + 1, kCFStringEncodingUTF8);
+#else
+  CFStringGetCString(cfname, mname, length * 3 + 1, CFStringGetSystemEncoding());
+#endif
+  info.name.append( (const char *)mname, strlen(mname) );
+  info.name.append( ": " );
+  CFRelease( cfname );
+  free(mname);
+
+  property.mSelector = kAudioObjectPropertyName;
+  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &cfname );
+  if ( result != noErr ) {
+    errorStream_ << "RtApiCore::probeDeviceInfo: system error (" << getErrorCode( result ) << ") getting device name.";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  //const char *name = CFStringGetCStringPtr( cfname, CFStringGetSystemEncoding() );
+  length = CFStringGetLength(cfname);
+  char *name = (char *)malloc(length * 3 + 1);
+#if defined( UNICODE ) || defined( _UNICODE )
+  CFStringGetCString(cfname, name, length * 3 + 1, kCFStringEncodingUTF8);
+#else
+  CFStringGetCString(cfname, name, length * 3 + 1, CFStringGetSystemEncoding());
+#endif
+  info.name.append( (const char *)name, strlen(name) );
+  CFRelease( cfname );
+  free(name);
+
+  // Get the output stream "configuration".
+  AudioBufferList	*bufferList = nil;
+  property.mSelector = kAudioDevicePropertyStreamConfiguration;
+  property.mScope = kAudioDevicePropertyScopeOutput;
+  //  property.mElement = kAudioObjectPropertyElementWildcard;
+  dataSize = 0;
+  result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize );
+  if ( result != noErr || dataSize == 0 ) {
+    errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting output stream configuration info for device (" << device << ").";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // Allocate the AudioBufferList.
+  bufferList = (AudioBufferList *) malloc( dataSize );
+  if ( bufferList == NULL ) {
+    errorText_ = "RtApiCore::getDeviceInfo: memory error allocating output AudioBufferList.";
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList );
+  if ( result != noErr || dataSize == 0 ) {
+    free( bufferList );
+    errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting output stream configuration for device (" << device << ").";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // Get output channel information.
+  unsigned int i, nStreams = bufferList->mNumberBuffers;
+  for ( i=0; i<nStreams; i++ )
+    info.outputChannels += bufferList->mBuffers[i].mNumberChannels;
+  free( bufferList );
+
+  // Get the input stream "configuration".
+  property.mScope = kAudioDevicePropertyScopeInput;
+  result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize );
+  if ( result != noErr || dataSize == 0 ) {
+    errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting input stream configuration info for device (" << device << ").";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // Allocate the AudioBufferList.
+  bufferList = (AudioBufferList *) malloc( dataSize );
+  if ( bufferList == NULL ) {
+    errorText_ = "RtApiCore::getDeviceInfo: memory error allocating input AudioBufferList.";
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList );
+  if (result != noErr || dataSize == 0) {
+    free( bufferList );
+    errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting input stream configuration for device (" << device << ").";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // Get input channel information.
+  nStreams = bufferList->mNumberBuffers;
+  for ( i=0; i<nStreams; i++ )
+    info.inputChannels += bufferList->mBuffers[i].mNumberChannels;
+  free( bufferList );
+
+  // If device opens for both playback and capture, we determine the channels.
+  if ( info.outputChannels > 0 && info.inputChannels > 0 )
+    info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
+
+  // Probe the device sample rates.
+  bool isInput = false;
+  if ( info.outputChannels == 0 ) isInput = true;
+
+  // Determine the supported sample rates.
+  property.mSelector = kAudioDevicePropertyAvailableNominalSampleRates;
+  if ( isInput == false ) property.mScope = kAudioDevicePropertyScopeOutput;
+  result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize );
+  if ( result != kAudioHardwareNoError || dataSize == 0 ) {
+    errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting sample rate info.";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  UInt32 nRanges = dataSize / sizeof( AudioValueRange );
+  AudioValueRange rangeList[ nRanges ];
+  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &rangeList );
+  if ( result != kAudioHardwareNoError ) {
+    errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting sample rates.";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // The sample rate reporting mechanism is a bit of a mystery.  It
+  // seems that it can either return individual rates or a range of
+  // rates.  I assume that if the min / max range values are the same,
+  // then that represents a single supported rate and if the min / max
+  // range values are different, the device supports an arbitrary
+  // range of values (though there might be multiple ranges, so we'll
+  // use the most conservative range).
+  Float64 minimumRate = 1.0, maximumRate = 10000000000.0;
+  bool haveValueRange = false;
+  info.sampleRates.clear();
+  for ( UInt32 i=0; i<nRanges; i++ ) {
+    if ( rangeList[i].mMinimum == rangeList[i].mMaximum )
+      info.sampleRates.push_back( (unsigned int) rangeList[i].mMinimum );
+    else {
+      haveValueRange = true;
+      if ( rangeList[i].mMinimum > minimumRate ) minimumRate = rangeList[i].mMinimum;
+      if ( rangeList[i].mMaximum < maximumRate ) maximumRate = rangeList[i].mMaximum;
+    }
+  }
+
+  if ( haveValueRange ) {
+    for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
+      if ( SAMPLE_RATES[k] >= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate )
+        info.sampleRates.push_back( SAMPLE_RATES[k] );
+    }
+  }
+
+  // Sort and remove any redundant values
+  std::sort( info.sampleRates.begin(), info.sampleRates.end() );
+  info.sampleRates.erase( unique( info.sampleRates.begin(), info.sampleRates.end() ), info.sampleRates.end() );
+
+  if ( info.sampleRates.size() == 0 ) {
+    errorStream_ << "RtApiCore::probeDeviceInfo: No supported sample rates found for device (" << device << ").";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // CoreAudio always uses 32-bit floating point data for PCM streams.
+  // Thus, any other "physical" formats supported by the device are of
+  // no interest to the client.
+  info.nativeFormats = RTAUDIO_FLOAT32;
+
+  if ( info.outputChannels > 0 )
+    if ( getDefaultOutputDevice() == device ) info.isDefaultOutput = true;
+  if ( info.inputChannels > 0 )
+    if ( getDefaultInputDevice() == device ) info.isDefaultInput = true;
+
+  info.probed = true;
+  return info;
+}
+
+static OSStatus callbackHandler( AudioDeviceID inDevice,
+                                 const AudioTimeStamp* /*inNow*/,
+                                 const AudioBufferList* inInputData,
+                                 const AudioTimeStamp* /*inInputTime*/,
+                                 AudioBufferList* outOutputData,
+                                 const AudioTimeStamp* /*inOutputTime*/,
+                                 void* infoPointer )
+{
+  CallbackInfo *info = (CallbackInfo *) infoPointer;
+
+  RtApiCore *object = (RtApiCore *) info->object;
+  if ( object->callbackEvent( inDevice, inInputData, outOutputData ) == false )
+    return kAudioHardwareUnspecifiedError;
+  else
+    return kAudioHardwareNoError;
+}
+
+static OSStatus xrunListener( AudioObjectID /*inDevice*/,
+                              UInt32 nAddresses,
+                              const AudioObjectPropertyAddress properties[],
+                              void* handlePointer )
+{
+  CoreHandle *handle = (CoreHandle *) handlePointer;
+  for ( UInt32 i=0; i<nAddresses; i++ ) {
+    if ( properties[i].mSelector == kAudioDeviceProcessorOverload ) {
+      if ( properties[i].mScope == kAudioDevicePropertyScopeInput )
+        handle->xrun[1] = true;
+      else
+        handle->xrun[0] = true;
+    }
+  }
+
+  return kAudioHardwareNoError;
+}
+
+static OSStatus rateListener( AudioObjectID inDevice,
+                              UInt32 /*nAddresses*/,
+                              const AudioObjectPropertyAddress /*properties*/[],
+                              void* ratePointer )
+{
+  Float64 *rate = (Float64 *) ratePointer;
+  UInt32 dataSize = sizeof( Float64 );
+  AudioObjectPropertyAddress property = { kAudioDevicePropertyNominalSampleRate,
+                                          kAudioObjectPropertyScopeGlobal,
+                                          kAudioObjectPropertyElementMaster };
+  AudioObjectGetPropertyData( inDevice, &property, 0, NULL, &dataSize, rate );
+  return kAudioHardwareNoError;
+}
+
+bool RtApiCore :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
+                                   unsigned int firstChannel, unsigned int sampleRate,
+                                   RtAudioFormat format, unsigned int *bufferSize,
+                                   RtAudio::StreamOptions *options )
+{
+  // Get device ID
+  unsigned int nDevices = getDeviceCount();
+  if ( nDevices == 0 ) {
+    // This should not happen because a check is made before this function is called.
+    errorText_ = "RtApiCore::probeDeviceOpen: no devices found!";
+    return FAILURE;
+  }
+
+  if ( device >= nDevices ) {
+    // This should not happen because a check is made before this function is called.
+    errorText_ = "RtApiCore::probeDeviceOpen: device ID is invalid!";
+    return FAILURE;
+  }
+
+  AudioDeviceID deviceList[ nDevices ];
+  UInt32 dataSize = sizeof( AudioDeviceID ) * nDevices;
+  AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
+                                          kAudioObjectPropertyScopeGlobal,
+                                          kAudioObjectPropertyElementMaster };
+  OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property,
+                                                0, NULL, &dataSize, (void *) &deviceList );
+  if ( result != noErr ) {
+    errorText_ = "RtApiCore::probeDeviceOpen: OS-X system error getting device IDs.";
+    return FAILURE;
+  }
+
+  AudioDeviceID id = deviceList[ device ];
+
+  // Setup for stream mode.
+  bool isInput = false;
+  if ( mode == INPUT ) {
+    isInput = true;
+    property.mScope = kAudioDevicePropertyScopeInput;
+  }
+  else
+    property.mScope = kAudioDevicePropertyScopeOutput;
+
+  // Get the stream "configuration".
+  AudioBufferList	*bufferList = nil;
+  dataSize = 0;
+  property.mSelector = kAudioDevicePropertyStreamConfiguration;
+  result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize );
+  if ( result != noErr || dataSize == 0 ) {
+    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream configuration info for device (" << device << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Allocate the AudioBufferList.
+  bufferList = (AudioBufferList *) malloc( dataSize );
+  if ( bufferList == NULL ) {
+    errorText_ = "RtApiCore::probeDeviceOpen: memory error allocating AudioBufferList.";
+    return FAILURE;
+  }
+
+  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList );
+  if (result != noErr || dataSize == 0) {
+    free( bufferList );
+    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream configuration for device (" << device << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Search for one or more streams that contain the desired number of
+  // channels. CoreAudio devices can have an arbitrary number of
+  // streams and each stream can have an arbitrary number of channels.
+  // For each stream, a single buffer of interleaved samples is
+  // provided.  RtAudio prefers the use of one stream of interleaved
+  // data or multiple consecutive single-channel streams.  However, we
+  // now support multiple consecutive multi-channel streams of
+  // interleaved data as well.
+  UInt32 iStream, offsetCounter = firstChannel;
+  UInt32 nStreams = bufferList->mNumberBuffers;
+  bool monoMode = false;
+  bool foundStream = false;
+
+  // First check that the device supports the requested number of
+  // channels.
+  UInt32 deviceChannels = 0;
+  for ( iStream=0; iStream<nStreams; iStream++ )
+    deviceChannels += bufferList->mBuffers[iStream].mNumberChannels;
+
+  if ( deviceChannels < ( channels + firstChannel ) ) {
+    free( bufferList );
+    errorStream_ << "RtApiCore::probeDeviceOpen: the device (" << device << ") does not support the requested channel count.";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Look for a single stream meeting our needs.
+  UInt32 firstStream, streamCount = 1, streamChannels = 0, channelOffset = 0;
+  for ( iStream=0; iStream<nStreams; iStream++ ) {
+    streamChannels = bufferList->mBuffers[iStream].mNumberChannels;
+    if ( streamChannels >= channels + offsetCounter ) {
+      firstStream = iStream;
+      channelOffset = offsetCounter;
+      foundStream = true;
+      break;
+    }
+    if ( streamChannels > offsetCounter ) break;
+    offsetCounter -= streamChannels;
+  }
+
+  // If we didn't find a single stream above, then we should be able
+  // to meet the channel specification with multiple streams.
+  if ( foundStream == false ) {
+    monoMode = true;
+    offsetCounter = firstChannel;
+    for ( iStream=0; iStream<nStreams; iStream++ ) {
+      streamChannels = bufferList->mBuffers[iStream].mNumberChannels;
+      if ( streamChannels > offsetCounter ) break;
+      offsetCounter -= streamChannels;
+    }
+
+    firstStream = iStream;
+    channelOffset = offsetCounter;
+    Int32 channelCounter = channels + offsetCounter - streamChannels;
+
+    if ( streamChannels > 1 ) monoMode = false;
+    while ( channelCounter > 0 ) {
+      streamChannels = bufferList->mBuffers[++iStream].mNumberChannels;
+      if ( streamChannels > 1 ) monoMode = false;
+      channelCounter -= streamChannels;
+      streamCount++;
+    }
+  }
+
+  free( bufferList );
+
+  // Determine the buffer size.
+  AudioValueRange	bufferRange;
+  dataSize = sizeof( AudioValueRange );
+  property.mSelector = kAudioDevicePropertyBufferFrameSizeRange;
+  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &bufferRange );
+
+  if ( result != noErr ) {
+    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting buffer size range for device (" << device << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  if ( bufferRange.mMinimum > *bufferSize ) *bufferSize = (unsigned long) bufferRange.mMinimum;
+  else if ( bufferRange.mMaximum < *bufferSize ) *bufferSize = (unsigned long) bufferRange.mMaximum;
+  if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) *bufferSize = (unsigned long) bufferRange.mMinimum;
+
+  // Set the buffer size.  For multiple streams, I'm assuming we only
+  // need to make this setting for the master channel.
+  UInt32 theSize = (UInt32) *bufferSize;
+  dataSize = sizeof( UInt32 );
+  property.mSelector = kAudioDevicePropertyBufferFrameSize;
+  result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &theSize );
+
+  if ( result != noErr ) {
+    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting the buffer size for device (" << device << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // If attempting to setup a duplex stream, the bufferSize parameter
+  // MUST be the same in both directions!
+  *bufferSize = theSize;
+  if ( stream_.mode == OUTPUT && mode == INPUT && *bufferSize != stream_.bufferSize ) {
+    errorStream_ << "RtApiCore::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << device << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  stream_.bufferSize = *bufferSize;
+  stream_.nBuffers = 1;
+
+  // Try to set "hog" mode ... it's not clear to me this is working.
+  if ( options && options->flags & RTAUDIO_HOG_DEVICE ) {
+    pid_t hog_pid;
+    dataSize = sizeof( hog_pid );
+    property.mSelector = kAudioDevicePropertyHogMode;
+    result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &hog_pid );
+    if ( result != noErr ) {
+      errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting 'hog' state!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    if ( hog_pid != getpid() ) {
+      hog_pid = getpid();
+      result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &hog_pid );
+      if ( result != noErr ) {
+        errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting 'hog' state!";
+        errorText_ = errorStream_.str();
+        return FAILURE;
+      }
+    }
+  }
+
+  // Check and if necessary, change the sample rate for the device.
+  Float64 nominalRate;
+  dataSize = sizeof( Float64 );
+  property.mSelector = kAudioDevicePropertyNominalSampleRate;
+  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &nominalRate );
+  if ( result != noErr ) {
+    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting current sample rate.";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Only change the sample rate if off by more than 1 Hz.
+  if ( fabs( nominalRate - (double)sampleRate ) > 1.0 ) {
+
+    // Set a property listener for the sample rate change
+    Float64 reportedRate = 0.0;
+    AudioObjectPropertyAddress tmp = { kAudioDevicePropertyNominalSampleRate, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
+    result = AudioObjectAddPropertyListener( id, &tmp, rateListener, (void *) &reportedRate );
+    if ( result != noErr ) {
+      errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate property listener for device (" << device << ").";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    nominalRate = (Float64) sampleRate;
+    result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &nominalRate );
+    if ( result != noErr ) {
+      AudioObjectRemovePropertyListener( id, &tmp, rateListener, (void *) &reportedRate );
+      errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate for device (" << device << ").";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    // Now wait until the reported nominal rate is what we just set.
+    UInt32 microCounter = 0;
+    while ( reportedRate != nominalRate ) {
+      microCounter += 5000;
+      if ( microCounter > 5000000 ) break;
+      usleep( 5000 );
+    }
+
+    // Remove the property listener.
+    AudioObjectRemovePropertyListener( id, &tmp, rateListener, (void *) &reportedRate );
+
+    if ( microCounter > 5000000 ) {
+      errorStream_ << "RtApiCore::probeDeviceOpen: timeout waiting for sample rate update for device (" << device << ").";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+  }
+
+  // Now set the stream format for all streams.  Also, check the
+  // physical format of the device and change that if necessary.
+  AudioStreamBasicDescription	description;
+  dataSize = sizeof( AudioStreamBasicDescription );
+  property.mSelector = kAudioStreamPropertyVirtualFormat;
+  result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &description );
+  if ( result != noErr ) {
+    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream format for device (" << device << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Set the sample rate and data format id.  However, only make the
+  // change if the sample rate is not within 1.0 of the desired
+  // rate and the format is not linear pcm.
+  bool updateFormat = false;
+  if ( fabs( description.mSampleRate - (Float64)sampleRate ) > 1.0 ) {
+    description.mSampleRate = (Float64) sampleRate;
+    updateFormat = true;
+  }
+
+  if ( description.mFormatID != kAudioFormatLinearPCM ) {
+    description.mFormatID = kAudioFormatLinearPCM;
+    updateFormat = true;
+  }
+
+  if ( updateFormat ) {
+    result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &description );
+    if ( result != noErr ) {
+      errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate or data format for device (" << device << ").";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+  }
+
+  // Now check the physical format.
+  property.mSelector = kAudioStreamPropertyPhysicalFormat;
+  result = AudioObjectGetPropertyData( id, &property, 0, NULL,  &dataSize, &description );
+  if ( result != noErr ) {
+    errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream physical format for device (" << device << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  //std::cout << "Current physical stream format:" << std::endl;
+  //std::cout << "   mBitsPerChan = " << description.mBitsPerChannel << std::endl;
+  //std::cout << "   aligned high = " << (description.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (description.mFormatFlags & kAudioFormatFlagIsPacked) << std::endl;
+  //std::cout << "   bytesPerFrame = " << description.mBytesPerFrame << std::endl;
+  //std::cout << "   sample rate = " << description.mSampleRate << std::endl;
+
+  if ( description.mFormatID != kAudioFormatLinearPCM || description.mBitsPerChannel < 16 ) {
+    description.mFormatID = kAudioFormatLinearPCM;
+    //description.mSampleRate = (Float64) sampleRate;
+    AudioStreamBasicDescription	testDescription = description;
+    UInt32 formatFlags;
+
+    // We'll try higher bit rates first and then work our way down.
+    std::vector< std::pair<UInt32, UInt32>  > physicalFormats;
+    formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsFloat) & ~kLinearPCMFormatFlagIsSignedInteger;
+    physicalFormats.push_back( std::pair<Float32, UInt32>( 32, formatFlags ) );
+    formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat;
+    physicalFormats.push_back( std::pair<Float32, UInt32>( 32, formatFlags ) );
+    physicalFormats.push_back( std::pair<Float32, UInt32>( 24, formatFlags ) );   // 24-bit packed
+    formatFlags &= ~( kAudioFormatFlagIsPacked | kAudioFormatFlagIsAlignedHigh );
+    physicalFormats.push_back( std::pair<Float32, UInt32>( 24.2, formatFlags ) ); // 24-bit in 4 bytes, aligned low
+    formatFlags |= kAudioFormatFlagIsAlignedHigh;
+    physicalFormats.push_back( std::pair<Float32, UInt32>( 24.4, formatFlags ) ); // 24-bit in 4 bytes, aligned high
+    formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat;
+    physicalFormats.push_back( std::pair<Float32, UInt32>( 16, formatFlags ) );
+    physicalFormats.push_back( std::pair<Float32, UInt32>( 8, formatFlags ) );
+
+    bool setPhysicalFormat = false;
+    for( unsigned int i=0; i<physicalFormats.size(); i++ ) {
+      testDescription = description;
+      testDescription.mBitsPerChannel = (UInt32) physicalFormats[i].first;
+      testDescription.mFormatFlags = physicalFormats[i].second;
+      if ( (24 == (UInt32)physicalFormats[i].first) && ~( physicalFormats[i].second & kAudioFormatFlagIsPacked ) )
+        testDescription.mBytesPerFrame =  4 * testDescription.mChannelsPerFrame;
+      else
+        testDescription.mBytesPerFrame =  testDescription.mBitsPerChannel/8 * testDescription.mChannelsPerFrame;
+      testDescription.mBytesPerPacket = testDescription.mBytesPerFrame * testDescription.mFramesPerPacket;
+      result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &testDescription );
+      if ( result == noErr ) {
+        setPhysicalFormat = true;
+        //std::cout << "Updated physical stream format:" << std::endl;
+        //std::cout << "   mBitsPerChan = " << testDescription.mBitsPerChannel << std::endl;
+        //std::cout << "   aligned high = " << (testDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (testDescription.mFormatFlags & kAudioFormatFlagIsPacked) << std::endl;
+        //std::cout << "   bytesPerFrame = " << testDescription.mBytesPerFrame << std::endl;
+        //std::cout << "   sample rate = " << testDescription.mSampleRate << std::endl;
+        break;
+      }
+    }
+
+    if ( !setPhysicalFormat ) {
+      errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting physical data format for device (" << device << ").";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+  } // done setting virtual/physical formats.
+
+  // Get the stream / device latency.
+  UInt32 latency;
+  dataSize = sizeof( UInt32 );
+  property.mSelector = kAudioDevicePropertyLatency;
+  if ( AudioObjectHasProperty( id, &property ) == true ) {
+    result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &latency );
+    if ( result == kAudioHardwareNoError ) stream_.latency[ mode ] = latency;
+    else {
+      errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting device latency for device (" << device << ").";
+      errorText_ = errorStream_.str();
+      error( RtAudioError::WARNING );
+    }
+  }
+
+  // Byte-swapping: According to AudioHardware.h, the stream data will
+  // always be presented in native-endian format, so we should never
+  // need to byte swap.
+  stream_.doByteSwap[mode] = false;
+
+  // From the CoreAudio documentation, PCM data must be supplied as
+  // 32-bit floats.
+  stream_.userFormat = format;
+  stream_.deviceFormat[mode] = RTAUDIO_FLOAT32;
+
+  if ( streamCount == 1 )
+    stream_.nDeviceChannels[mode] = description.mChannelsPerFrame;
+  else // multiple streams
+    stream_.nDeviceChannels[mode] = channels;
+  stream_.nUserChannels[mode] = channels;
+  stream_.channelOffset[mode] = channelOffset;  // offset within a CoreAudio stream
+  if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
+  else stream_.userInterleaved = true;
+  stream_.deviceInterleaved[mode] = true;
+  if ( monoMode == true ) stream_.deviceInterleaved[mode] = false;
+
+  // Set flags for buffer conversion.
+  stream_.doConvertBuffer[mode] = false;
+  if ( stream_.userFormat != stream_.deviceFormat[mode] )
+    stream_.doConvertBuffer[mode] = true;
+  if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] )
+    stream_.doConvertBuffer[mode] = true;
+  if ( streamCount == 1 ) {
+    if ( stream_.nUserChannels[mode] > 1 &&
+         stream_.userInterleaved != stream_.deviceInterleaved[mode] )
+      stream_.doConvertBuffer[mode] = true;
+  }
+  else if ( monoMode && stream_.userInterleaved )
+    stream_.doConvertBuffer[mode] = true;
+
+  // Allocate our CoreHandle structure for the stream.
+  CoreHandle *handle = 0;
+  if ( stream_.apiHandle == 0 ) {
+    try {
+      handle = new CoreHandle;
+    }
+    catch ( std::bad_alloc& ) {
+      errorText_ = "RtApiCore::probeDeviceOpen: error allocating CoreHandle memory.";
+      goto error;
+    }
+
+    if ( pthread_cond_init( &handle->condition, NULL ) ) {
+      errorText_ = "RtApiCore::probeDeviceOpen: error initializing pthread condition variable.";
+      goto error;
+    }
+    stream_.apiHandle = (void *) handle;
+  }
+  else
+    handle = (CoreHandle *) stream_.apiHandle;
+  handle->iStream[mode] = firstStream;
+  handle->nStreams[mode] = streamCount;
+  handle->id[mode] = id;
+
+  // Allocate necessary internal buffers.
+  unsigned long bufferBytes;
+  bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
+  //  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
+  stream_.userBuffer[mode] = (char *) malloc( bufferBytes * sizeof(char) );
+  memset( stream_.userBuffer[mode], 0, bufferBytes * sizeof(char) );
+  if ( stream_.userBuffer[mode] == NULL ) {
+    errorText_ = "RtApiCore::probeDeviceOpen: error allocating user buffer memory.";
+    goto error;
+  }
+
+  // If possible, we will make use of the CoreAudio stream buffers as
+  // "device buffers".  However, we can't do this if using multiple
+  // streams.
+  if ( stream_.doConvertBuffer[mode] && handle->nStreams[mode] > 1 ) {
+
+    bool makeBuffer = true;
+    bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
+    if ( mode == INPUT ) {
+      if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
+        unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
+        if ( bufferBytes <= bytesOut ) makeBuffer = false;
+      }
+    }
+
+    if ( makeBuffer ) {
+      bufferBytes *= *bufferSize;
+      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
+      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
+      if ( stream_.deviceBuffer == NULL ) {
+        errorText_ = "RtApiCore::probeDeviceOpen: error allocating device buffer memory.";
+        goto error;
+      }
+    }
+  }
+
+  stream_.sampleRate = sampleRate;
+  stream_.device[mode] = device;
+  stream_.state = STREAM_STOPPED;
+  stream_.callbackInfo.object = (void *) this;
+
+  // Setup the buffer conversion information structure.
+  if ( stream_.doConvertBuffer[mode] ) {
+    if ( streamCount > 1 ) setConvertInfo( mode, 0 );
+    else setConvertInfo( mode, channelOffset );
+  }
+
+  if ( mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] == device )
+    // Only one callback procedure per device.
+    stream_.mode = DUPLEX;
+  else {
+#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
+    result = AudioDeviceCreateIOProcID( id, callbackHandler, (void *) &stream_.callbackInfo, &handle->procId[mode] );
+#else
+    // deprecated in favor of AudioDeviceCreateIOProcID()
+    result = AudioDeviceAddIOProc( id, callbackHandler, (void *) &stream_.callbackInfo );
+#endif
+    if ( result != noErr ) {
+      errorStream_ << "RtApiCore::probeDeviceOpen: system error setting callback for device (" << device << ").";
+      errorText_ = errorStream_.str();
+      goto error;
+    }
+    if ( stream_.mode == OUTPUT && mode == INPUT )
+      stream_.mode = DUPLEX;
+    else
+      stream_.mode = mode;
+  }
+
+  // Setup the device property listener for over/underload.
+  property.mSelector = kAudioDeviceProcessorOverload;
+  property.mScope = kAudioObjectPropertyScopeGlobal;
+  result = AudioObjectAddPropertyListener( id, &property, xrunListener, (void *) handle );
+
+  return SUCCESS;
+
+ error:
+  if ( handle ) {
+    pthread_cond_destroy( &handle->condition );
+    delete handle;
+    stream_.apiHandle = 0;
+  }
+
+  for ( int i=0; i<2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  stream_.state = STREAM_CLOSED;
+  return FAILURE;
+}
+
+void RtApiCore :: closeStream( void )
+{
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiCore::closeStream(): no open stream to close!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+    if ( stream_.state == STREAM_RUNNING )
+      AudioDeviceStop( handle->id[0], callbackHandler );
+#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
+    AudioDeviceDestroyIOProcID( handle->id[0], handle->procId[0] );
+#else
+    // deprecated in favor of AudioDeviceDestroyIOProcID()
+    AudioDeviceRemoveIOProc( handle->id[0], callbackHandler );
+#endif
+  }
+
+  if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) {
+    if ( stream_.state == STREAM_RUNNING )
+      AudioDeviceStop( handle->id[1], callbackHandler );
+#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
+    AudioDeviceDestroyIOProcID( handle->id[1], handle->procId[1] );
+#else
+    // deprecated in favor of AudioDeviceDestroyIOProcID()
+    AudioDeviceRemoveIOProc( handle->id[1], callbackHandler );
+#endif
+  }
+
+  for ( int i=0; i<2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  // Destroy pthread condition variable.
+  pthread_cond_destroy( &handle->condition );
+  delete handle;
+  stream_.apiHandle = 0;
+
+  stream_.mode = UNINITIALIZED;
+  stream_.state = STREAM_CLOSED;
+}
+
+void RtApiCore :: startStream( void )
+{
+  verifyStream();
+  if ( stream_.state == STREAM_RUNNING ) {
+    errorText_ = "RtApiCore::startStream(): the stream is already running!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  OSStatus result = noErr;
+  CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+
+    result = AudioDeviceStart( handle->id[0], callbackHandler );
+    if ( result != noErr ) {
+      errorStream_ << "RtApiCore::startStream: system error (" << getErrorCode( result ) << ") starting callback procedure on device (" << stream_.device[0] << ").";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+  }
+
+  if ( stream_.mode == INPUT ||
+       ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) {
+
+    result = AudioDeviceStart( handle->id[1], callbackHandler );
+    if ( result != noErr ) {
+      errorStream_ << "RtApiCore::startStream: system error starting input callback procedure on device (" << stream_.device[1] << ").";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+  }
+
+  handle->drainCounter = 0;
+  handle->internalDrain = false;
+  stream_.state = STREAM_RUNNING;
+
+ unlock:
+  if ( result == noErr ) return;
+  error( RtAudioError::SYSTEM_ERROR );
+}
+
+void RtApiCore :: stopStream( void )
+{
+  verifyStream();
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiCore::stopStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  OSStatus result = noErr;
+  CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+
+    if ( handle->drainCounter == 0 ) {
+      handle->drainCounter = 2;
+      pthread_cond_wait( &handle->condition, &stream_.mutex ); // block until signaled
+    }
+
+    result = AudioDeviceStop( handle->id[0], callbackHandler );
+    if ( result != noErr ) {
+      errorStream_ << "RtApiCore::stopStream: system error (" << getErrorCode( result ) << ") stopping callback procedure on device (" << stream_.device[0] << ").";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+  }
+
+  if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) {
+
+    result = AudioDeviceStop( handle->id[1], callbackHandler );
+    if ( result != noErr ) {
+      errorStream_ << "RtApiCore::stopStream: system error (" << getErrorCode( result ) << ") stopping input callback procedure on device (" << stream_.device[1] << ").";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+  }
+
+  stream_.state = STREAM_STOPPED;
+
+ unlock:
+  if ( result == noErr ) return;
+  error( RtAudioError::SYSTEM_ERROR );
+}
+
+void RtApiCore :: abortStream( void )
+{
+  verifyStream();
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiCore::abortStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
+  handle->drainCounter = 2;
+
+  stopStream();
+}
+
+// This function will be called by a spawned thread when the user
+// callback function signals that the stream should be stopped or
+// aborted.  It is better to handle it this way because the
+// callbackEvent() function probably should return before the AudioDeviceStop()
+// function is called.
+static void *coreStopStream( void *ptr )
+{
+  CallbackInfo *info = (CallbackInfo *) ptr;
+  RtApiCore *object = (RtApiCore *) info->object;
+
+  object->stopStream();
+  pthread_exit( NULL );
+}
+
+bool RtApiCore :: callbackEvent( AudioDeviceID deviceId,
+                                 const AudioBufferList *inBufferList,
+                                 const AudioBufferList *outBufferList )
+{
+  if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS;
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!";
+    error( RtAudioError::WARNING );
+    return FAILURE;
+  }
+
+  CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
+  CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
+
+  // Check if we were draining the stream and signal is finished.
+  if ( handle->drainCounter > 3 ) {
+    ThreadHandle threadId;
+
+    stream_.state = STREAM_STOPPING;
+    if ( handle->internalDrain == true )
+      pthread_create( &threadId, NULL, coreStopStream, info );
+    else // external call to stopStream()
+      pthread_cond_signal( &handle->condition );
+    return SUCCESS;
+  }
+
+  AudioDeviceID outputDevice = handle->id[0];
+
+  // Invoke user callback to get fresh output data UNLESS we are
+  // draining stream or duplex mode AND the input/output devices are
+  // different AND this function is called for the input device.
+  if ( handle->drainCounter == 0 && ( stream_.mode != DUPLEX || deviceId == outputDevice ) ) {
+    RtAudioCallback callback = (RtAudioCallback) info->callback;
+    double streamTime = getStreamTime();
+    RtAudioStreamStatus status = 0;
+    if ( stream_.mode != INPUT && handle->xrun[0] == true ) {
+      status |= RTAUDIO_OUTPUT_UNDERFLOW;
+      handle->xrun[0] = false;
+    }
+    if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) {
+      status |= RTAUDIO_INPUT_OVERFLOW;
+      handle->xrun[1] = false;
+    }
+
+    int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
+                                  stream_.bufferSize, streamTime, status, info->userData );
+    if ( cbReturnValue == 2 ) {
+      stream_.state = STREAM_STOPPING;
+      handle->drainCounter = 2;
+      abortStream();
+      return SUCCESS;
+    }
+    else if ( cbReturnValue == 1 ) {
+      handle->drainCounter = 1;
+      handle->internalDrain = true;
+    }
+  }
+
+  if ( stream_.mode == OUTPUT || ( stream_.mode == DUPLEX && deviceId == outputDevice ) ) {
+
+    if ( handle->drainCounter > 1 ) { // write zeros to the output stream
+
+      if ( handle->nStreams[0] == 1 ) {
+        memset( outBufferList->mBuffers[handle->iStream[0]].mData,
+                0,
+                outBufferList->mBuffers[handle->iStream[0]].mDataByteSize );
+      }
+      else { // fill multiple streams with zeros
+        for ( unsigned int i=0; i<handle->nStreams[0]; i++ ) {
+          memset( outBufferList->mBuffers[handle->iStream[0]+i].mData,
+                  0,
+                  outBufferList->mBuffers[handle->iStream[0]+i].mDataByteSize );
+        }
+      }
+    }
+    else if ( handle->nStreams[0] == 1 ) {
+      if ( stream_.doConvertBuffer[0] ) { // convert directly to CoreAudio stream buffer
+        convertBuffer( (char *) outBufferList->mBuffers[handle->iStream[0]].mData,
+                       stream_.userBuffer[0], stream_.convertInfo[0] );
+      }
+      else { // copy from user buffer
+        memcpy( outBufferList->mBuffers[handle->iStream[0]].mData,
+                stream_.userBuffer[0],
+                outBufferList->mBuffers[handle->iStream[0]].mDataByteSize );
+      }
+    }
+    else { // fill multiple streams
+      Float32 *inBuffer = (Float32 *) stream_.userBuffer[0];
+      if ( stream_.doConvertBuffer[0] ) {
+        convertBuffer( stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0] );
+        inBuffer = (Float32 *) stream_.deviceBuffer;
+      }
+
+      if ( stream_.deviceInterleaved[0] == false ) { // mono mode
+        UInt32 bufferBytes = outBufferList->mBuffers[handle->iStream[0]].mDataByteSize;
+        for ( unsigned int i=0; i<stream_.nUserChannels[0]; i++ ) {
+          memcpy( outBufferList->mBuffers[handle->iStream[0]+i].mData,
+                  (void *)&inBuffer[i*stream_.bufferSize], bufferBytes );
+        }
+      }
+      else { // fill multiple multi-channel streams with interleaved data
+        UInt32 streamChannels, channelsLeft, inJump, outJump, inOffset;
+        Float32 *out, *in;
+
+        bool inInterleaved = ( stream_.userInterleaved ) ? true : false;
+        UInt32 inChannels = stream_.nUserChannels[0];
+        if ( stream_.doConvertBuffer[0] ) {
+          inInterleaved = true; // device buffer will always be interleaved for nStreams > 1 and not mono mode
+          inChannels = stream_.nDeviceChannels[0];
+        }
+
+        if ( inInterleaved ) inOffset = 1;
+        else inOffset = stream_.bufferSize;
+
+        channelsLeft = inChannels;
+        for ( unsigned int i=0; i<handle->nStreams[0]; i++ ) {
+          in = inBuffer;
+          out = (Float32 *) outBufferList->mBuffers[handle->iStream[0]+i].mData;
+          streamChannels = outBufferList->mBuffers[handle->iStream[0]+i].mNumberChannels;
+
+          outJump = 0;
+          // Account for possible channel offset in first stream
+          if ( i == 0 && stream_.channelOffset[0] > 0 ) {
+            streamChannels -= stream_.channelOffset[0];
+            outJump = stream_.channelOffset[0];
+            out += outJump;
+          }
+
+          // Account for possible unfilled channels at end of the last stream
+          if ( streamChannels > channelsLeft ) {
+            outJump = streamChannels - channelsLeft;
+            streamChannels = channelsLeft;
+          }
+
+          // Determine input buffer offsets and skips
+          if ( inInterleaved ) {
+            inJump = inChannels;
+            in += inChannels - channelsLeft;
+          }
+          else {
+            inJump = 1;
+            in += (inChannels - channelsLeft) * inOffset;
+          }
+
+          for ( unsigned int i=0; i<stream_.bufferSize; i++ ) {
+            for ( unsigned int j=0; j<streamChannels; j++ ) {
+              *out++ = in[j*inOffset];
+            }
+            out += outJump;
+            in += inJump;
+          }
+          channelsLeft -= streamChannels;
+        }
+      }
+    }
+  }
+
+  // Don't bother draining input
+  if ( handle->drainCounter ) {
+    handle->drainCounter++;
+    goto unlock;
+  }
+
+  AudioDeviceID inputDevice;
+  inputDevice = handle->id[1];
+  if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && deviceId == inputDevice ) ) {
+
+    if ( handle->nStreams[1] == 1 ) {
+      if ( stream_.doConvertBuffer[1] ) { // convert directly from CoreAudio stream buffer
+        convertBuffer( stream_.userBuffer[1],
+                       (char *) inBufferList->mBuffers[handle->iStream[1]].mData,
+                       stream_.convertInfo[1] );
+      }
+      else { // copy to user buffer
+        memcpy( stream_.userBuffer[1],
+                inBufferList->mBuffers[handle->iStream[1]].mData,
+                inBufferList->mBuffers[handle->iStream[1]].mDataByteSize );
+      }
+    }
+    else { // read from multiple streams
+      Float32 *outBuffer = (Float32 *) stream_.userBuffer[1];
+      if ( stream_.doConvertBuffer[1] ) outBuffer = (Float32 *) stream_.deviceBuffer;
+
+      if ( stream_.deviceInterleaved[1] == false ) { // mono mode
+        UInt32 bufferBytes = inBufferList->mBuffers[handle->iStream[1]].mDataByteSize;
+        for ( unsigned int i=0; i<stream_.nUserChannels[1]; i++ ) {
+          memcpy( (void *)&outBuffer[i*stream_.bufferSize],
+                  inBufferList->mBuffers[handle->iStream[1]+i].mData, bufferBytes );
+        }
+      }
+      else { // read from multiple multi-channel streams
+        UInt32 streamChannels, channelsLeft, inJump, outJump, outOffset;
+        Float32 *out, *in;
+
+        bool outInterleaved = ( stream_.userInterleaved ) ? true : false;
+        UInt32 outChannels = stream_.nUserChannels[1];
+        if ( stream_.doConvertBuffer[1] ) {
+          outInterleaved = true; // device buffer will always be interleaved for nStreams > 1 and not mono mode
+          outChannels = stream_.nDeviceChannels[1];
+        }
+
+        if ( outInterleaved ) outOffset = 1;
+        else outOffset = stream_.bufferSize;
+
+        channelsLeft = outChannels;
+        for ( unsigned int i=0; i<handle->nStreams[1]; i++ ) {
+          out = outBuffer;
+          in = (Float32 *) inBufferList->mBuffers[handle->iStream[1]+i].mData;
+          streamChannels = inBufferList->mBuffers[handle->iStream[1]+i].mNumberChannels;
+
+          inJump = 0;
+          // Account for possible channel offset in first stream
+          if ( i == 0 && stream_.channelOffset[1] > 0 ) {
+            streamChannels -= stream_.channelOffset[1];
+            inJump = stream_.channelOffset[1];
+            in += inJump;
+          }
+
+          // Account for possible unread channels at end of the last stream
+          if ( streamChannels > channelsLeft ) {
+            inJump = streamChannels - channelsLeft;
+            streamChannels = channelsLeft;
+          }
+
+          // Determine output buffer offsets and skips
+          if ( outInterleaved ) {
+            outJump = outChannels;
+            out += outChannels - channelsLeft;
+          }
+          else {
+            outJump = 1;
+            out += (outChannels - channelsLeft) * outOffset;
+          }
+
+          for ( unsigned int i=0; i<stream_.bufferSize; i++ ) {
+            for ( unsigned int j=0; j<streamChannels; j++ ) {
+              out[j*outOffset] = *in++;
+            }
+            out += outJump;
+            in += inJump;
+          }
+          channelsLeft -= streamChannels;
+        }
+      }
+      
+      if ( stream_.doConvertBuffer[1] ) { // convert from our internal "device" buffer
+        convertBuffer( stream_.userBuffer[1],
+                       stream_.deviceBuffer,
+                       stream_.convertInfo[1] );
+      }
+    }
+  }
+
+ unlock:
+  //MUTEX_UNLOCK( &stream_.mutex );
+
+  RtApi::tickStreamTime();
+  return SUCCESS;
+}
+
+const char* RtApiCore :: getErrorCode( OSStatus code )
+{
+  switch( code ) {
+
+  case kAudioHardwareNotRunningError:
+    return "kAudioHardwareNotRunningError";
+
+  case kAudioHardwareUnspecifiedError:
+    return "kAudioHardwareUnspecifiedError";
+
+  case kAudioHardwareUnknownPropertyError:
+    return "kAudioHardwareUnknownPropertyError";
+
+  case kAudioHardwareBadPropertySizeError:
+    return "kAudioHardwareBadPropertySizeError";
+
+  case kAudioHardwareIllegalOperationError:
+    return "kAudioHardwareIllegalOperationError";
+
+  case kAudioHardwareBadObjectError:
+    return "kAudioHardwareBadObjectError";
+
+  case kAudioHardwareBadDeviceError:
+    return "kAudioHardwareBadDeviceError";
+
+  case kAudioHardwareBadStreamError:
+    return "kAudioHardwareBadStreamError";
+
+  case kAudioHardwareUnsupportedOperationError:
+    return "kAudioHardwareUnsupportedOperationError";
+
+  case kAudioDeviceUnsupportedFormatError:
+    return "kAudioDeviceUnsupportedFormatError";
+
+  case kAudioDevicePermissionsError:
+    return "kAudioDevicePermissionsError";
+
+  default:
+    return "CoreAudio unknown error";
+  }
+}
+
+  //******************** End of __MACOSX_CORE__ *********************//
+#endif
+
+#if defined(__UNIX_JACK__)
+
+// JACK is a low-latency audio server, originally written for the
+// GNU/Linux operating system and now also ported to OS-X. It can
+// connect a number of different applications to an audio device, as
+// well as allowing them to share audio between themselves.
+//
+// When using JACK with RtAudio, "devices" refer to JACK clients that
+// have ports connected to the server.  The JACK server is typically
+// started in a terminal as follows:
+//
+// .jackd -d alsa -d hw:0
+//
+// or through an interface program such as qjackctl.  Many of the
+// parameters normally set for a stream are fixed by the JACK server
+// and can be specified when the JACK server is started.  In
+// particular,
+//
+// .jackd -d alsa -d hw:0 -r 44100 -p 512 -n 4
+//
+// specifies a sample rate of 44100 Hz, a buffer size of 512 sample
+// frames, and number of buffers = 4.  Once the server is running, it
+// is not possible to override these values.  If the values are not
+// specified in the command-line, the JACK server uses default values.
+//
+// The JACK server does not have to be running when an instance of
+// RtApiJack is created, though the function getDeviceCount() will
+// report 0 devices found until JACK has been started.  When no
+// devices are available (i.e., the JACK server is not running), a
+// stream cannot be opened.
+
+#include <jack/jack.h>
+#include <unistd.h>
+#include <cstdio>
+
+// A structure to hold various information related to the Jack API
+// implementation.
+struct JackHandle {
+  jack_client_t *client;
+  jack_port_t **ports[2];
+  std::string deviceName[2];
+  bool xrun[2];
+  pthread_cond_t condition;
+  int drainCounter;       // Tracks callback counts when draining
+  bool internalDrain;     // Indicates if stop is initiated from callback or not.
+
+  JackHandle()
+    :client(0), drainCounter(0), internalDrain(false) { ports[0] = 0; ports[1] = 0; xrun[0] = false; xrun[1] = false; }
+};
+
+static void jackSilentError( const char * ) {};
+
+RtApiJack :: RtApiJack()
+{
+  // Nothing to do here.
+#if !defined(__RTAUDIO_DEBUG__)
+  // Turn off Jack's internal error reporting.
+  jack_set_error_function( &jackSilentError );
+#endif
+}
+
+RtApiJack :: ~RtApiJack()
+{
+  if ( stream_.state != STREAM_CLOSED ) closeStream();
+}
+
+unsigned int RtApiJack :: getDeviceCount( void )
+{
+  // See if we can become a jack client.
+  jack_options_t options = (jack_options_t) ( JackNoStartServer ); //JackNullOption;
+  jack_status_t *status = NULL;
+  jack_client_t *client = jack_client_open( "RtApiJackCount", options, status );
+  if ( client == 0 ) return 0;
+
+  const char **ports;
+  std::string port, previousPort;
+  unsigned int nChannels = 0, nDevices = 0;
+  ports = jack_get_ports( client, NULL, NULL, 0 );
+  if ( ports ) {
+    // Parse the port names up to the first colon (:).
+    size_t iColon = 0;
+    do {
+      port = (char *) ports[ nChannels ];
+      iColon = port.find(":");
+      if ( iColon != std::string::npos ) {
+        port = port.substr( 0, iColon + 1 );
+        if ( port != previousPort ) {
+          nDevices++;
+          previousPort = port;
+        }
+      }
+    } while ( ports[++nChannels] );
+    free( ports );
+  }
+
+  jack_client_close( client );
+  return nDevices;
+}
+
+RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device )
+{
+  RtAudio::DeviceInfo info;
+  info.probed = false;
+
+  jack_options_t options = (jack_options_t) ( JackNoStartServer ); //JackNullOption
+  jack_status_t *status = NULL;
+  jack_client_t *client = jack_client_open( "RtApiJackInfo", options, status );
+  if ( client == 0 ) {
+    errorText_ = "RtApiJack::getDeviceInfo: Jack server not found or connection error!";
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  const char **ports;
+  std::string port, previousPort;
+  unsigned int nPorts = 0, nDevices = 0;
+  ports = jack_get_ports( client, NULL, NULL, 0 );
+  if ( ports ) {
+    // Parse the port names up to the first colon (:).
+    size_t iColon = 0;
+    do {
+      port = (char *) ports[ nPorts ];
+      iColon = port.find(":");
+      if ( iColon != std::string::npos ) {
+        port = port.substr( 0, iColon );
+        if ( port != previousPort ) {
+          if ( nDevices == device ) info.name = port;
+          nDevices++;
+          previousPort = port;
+        }
+      }
+    } while ( ports[++nPorts] );
+    free( ports );
+  }
+
+  if ( device >= nDevices ) {
+    jack_client_close( client );
+    errorText_ = "RtApiJack::getDeviceInfo: device ID is invalid!";
+    error( RtAudioError::INVALID_USE );
+    return info;
+  }
+
+  // Get the current jack server sample rate.
+  info.sampleRates.clear();
+  info.sampleRates.push_back( jack_get_sample_rate( client ) );
+
+  // Count the available ports containing the client name as device
+  // channels.  Jack "input ports" equal RtAudio output channels.
+  unsigned int nChannels = 0;
+  ports = jack_get_ports( client, info.name.c_str(), NULL, JackPortIsInput );
+  if ( ports ) {
+    while ( ports[ nChannels ] ) nChannels++;
+    free( ports );
+    info.outputChannels = nChannels;
+  }
+
+  // Jack "output ports" equal RtAudio input channels.
+  nChannels = 0;
+  ports = jack_get_ports( client, info.name.c_str(), NULL, JackPortIsOutput );
+  if ( ports ) {
+    while ( ports[ nChannels ] ) nChannels++;
+    free( ports );
+    info.inputChannels = nChannels;
+  }
+
+  if ( info.outputChannels == 0 && info.inputChannels == 0 ) {
+    jack_client_close(client);
+    errorText_ = "RtApiJack::getDeviceInfo: error determining Jack input/output channels!";
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // If device opens for both playback and capture, we determine the channels.
+  if ( info.outputChannels > 0 && info.inputChannels > 0 )
+    info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
+
+  // Jack always uses 32-bit floats.
+  info.nativeFormats = RTAUDIO_FLOAT32;
+
+  // Jack doesn't provide default devices so we'll use the first available one.
+  if ( device == 0 && info.outputChannels > 0 )
+    info.isDefaultOutput = true;
+  if ( device == 0 && info.inputChannels > 0 )
+    info.isDefaultInput = true;
+
+  jack_client_close(client);
+  info.probed = true;
+  return info;
+}
+
+static int jackCallbackHandler( jack_nframes_t nframes, void *infoPointer )
+{
+  CallbackInfo *info = (CallbackInfo *) infoPointer;
+
+  RtApiJack *object = (RtApiJack *) info->object;
+  if ( object->callbackEvent( (unsigned long) nframes ) == false ) return 1;
+
+  return 0;
+}
+
+// This function will be called by a spawned thread when the Jack
+// server signals that it is shutting down.  It is necessary to handle
+// it this way because the jackShutdown() function must return before
+// the jack_deactivate() function (in closeStream()) will return.
+static void *jackCloseStream( void *ptr )
+{
+  CallbackInfo *info = (CallbackInfo *) ptr;
+  RtApiJack *object = (RtApiJack *) info->object;
+
+  object->closeStream();
+
+  pthread_exit( NULL );
+}
+static void jackShutdown( void *infoPointer )
+{
+  CallbackInfo *info = (CallbackInfo *) infoPointer;
+  RtApiJack *object = (RtApiJack *) info->object;
+
+  // Check current stream state.  If stopped, then we'll assume this
+  // was called as a result of a call to RtApiJack::stopStream (the
+  // deactivation of a client handle causes this function to be called).
+  // If not, we'll assume the Jack server is shutting down or some
+  // other problem occurred and we should close the stream.
+  if ( object->isStreamRunning() == false ) return;
+
+  ThreadHandle threadId;
+  pthread_create( &threadId, NULL, jackCloseStream, info );
+  std::cerr << "\nRtApiJack: the Jack server is shutting down this client ... stream stopped and closed!!\n" << std::endl;
+}
+
+static int jackXrun( void *infoPointer )
+{
+  JackHandle *handle = (JackHandle *) infoPointer;
+
+  if ( handle->ports[0] ) handle->xrun[0] = true;
+  if ( handle->ports[1] ) handle->xrun[1] = true;
+
+  return 0;
+}
+
+bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
+                                   unsigned int firstChannel, unsigned int sampleRate,
+                                   RtAudioFormat format, unsigned int *bufferSize,
+                                   RtAudio::StreamOptions *options )
+{
+  JackHandle *handle = (JackHandle *) stream_.apiHandle;
+
+  // Look for jack server and try to become a client (only do once per stream).
+  jack_client_t *client = 0;
+  if ( mode == OUTPUT || ( mode == INPUT && stream_.mode != OUTPUT ) ) {
+    jack_options_t jackoptions = (jack_options_t) ( JackNoStartServer ); //JackNullOption;
+    jack_status_t *status = NULL;
+    if ( options && !options->streamName.empty() )
+      client = jack_client_open( options->streamName.c_str(), jackoptions, status );
+    else
+      client = jack_client_open( "RtApiJack", jackoptions, status );
+    if ( client == 0 ) {
+      errorText_ = "RtApiJack::probeDeviceOpen: Jack server not found or connection error!";
+      error( RtAudioError::WARNING );
+      return FAILURE;
+    }
+  }
+  else {
+    // The handle must have been created on an earlier pass.
+    client = handle->client;
+  }
+
+  const char **ports;
+  std::string port, previousPort, deviceName;
+  unsigned int nPorts = 0, nDevices = 0;
+  ports = jack_get_ports( client, NULL, NULL, 0 );
+  if ( ports ) {
+    // Parse the port names up to the first colon (:).
+    size_t iColon = 0;
+    do {
+      port = (char *) ports[ nPorts ];
+      iColon = port.find(":");
+      if ( iColon != std::string::npos ) {
+        port = port.substr( 0, iColon );
+        if ( port != previousPort ) {
+          if ( nDevices == device ) deviceName = port;
+          nDevices++;
+          previousPort = port;
+        }
+      }
+    } while ( ports[++nPorts] );
+    free( ports );
+  }
+
+  if ( device >= nDevices ) {
+    errorText_ = "RtApiJack::probeDeviceOpen: device ID is invalid!";
+    return FAILURE;
+  }
+
+  // Count the available ports containing the client name as device
+  // channels.  Jack "input ports" equal RtAudio output channels.
+  unsigned int nChannels = 0;
+  unsigned long flag = JackPortIsInput;
+  if ( mode == INPUT ) flag = JackPortIsOutput;
+  ports = jack_get_ports( client, deviceName.c_str(), NULL, flag );
+  if ( ports ) {
+    while ( ports[ nChannels ] ) nChannels++;
+    free( ports );
+  }
+
+  // Compare the jack ports for specified client to the requested number of channels.
+  if ( nChannels < (channels + firstChannel) ) {
+    errorStream_ << "RtApiJack::probeDeviceOpen: requested number of channels (" << channels << ") + offset (" << firstChannel << ") not found for specified device (" << device << ":" << deviceName << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Check the jack server sample rate.
+  unsigned int jackRate = jack_get_sample_rate( client );
+  if ( sampleRate != jackRate ) {
+    jack_client_close( client );
+    errorStream_ << "RtApiJack::probeDeviceOpen: the requested sample rate (" << sampleRate << ") is different than the JACK server rate (" << jackRate << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+  stream_.sampleRate = jackRate;
+
+  // Get the latency of the JACK port.
+  ports = jack_get_ports( client, deviceName.c_str(), NULL, flag );
+  if ( ports[ firstChannel ] ) {
+    // Added by Ge Wang
+    jack_latency_callback_mode_t cbmode = (mode == INPUT ? JackCaptureLatency : JackPlaybackLatency);
+    // the range (usually the min and max are equal)
+    jack_latency_range_t latrange; latrange.min = latrange.max = 0;
+    // get the latency range
+    jack_port_get_latency_range( jack_port_by_name( client, ports[firstChannel] ), cbmode, &latrange );
+    // be optimistic, use the min!
+    stream_.latency[mode] = latrange.min;
+    //stream_.latency[mode] = jack_port_get_latency( jack_port_by_name( client, ports[ firstChannel ] ) );
+  }
+  free( ports );
+
+  // The jack server always uses 32-bit floating-point data.
+  stream_.deviceFormat[mode] = RTAUDIO_FLOAT32;
+  stream_.userFormat = format;
+
+  if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
+  else stream_.userInterleaved = true;
+
+  // Jack always uses non-interleaved buffers.
+  stream_.deviceInterleaved[mode] = false;
+
+  // Jack always provides host byte-ordered data.
+  stream_.doByteSwap[mode] = false;
+
+  // Get the buffer size.  The buffer size and number of buffers
+  // (periods) is set when the jack server is started.
+  stream_.bufferSize = (int) jack_get_buffer_size( client );
+  *bufferSize = stream_.bufferSize;
+
+  stream_.nDeviceChannels[mode] = channels;
+  stream_.nUserChannels[mode] = channels;
+
+  // Set flags for buffer conversion.
+  stream_.doConvertBuffer[mode] = false;
+  if ( stream_.userFormat != stream_.deviceFormat[mode] )
+    stream_.doConvertBuffer[mode] = true;
+  if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
+       stream_.nUserChannels[mode] > 1 )
+    stream_.doConvertBuffer[mode] = true;
+
+  // Allocate our JackHandle structure for the stream.
+  if ( handle == 0 ) {
+    try {
+      handle = new JackHandle;
+    }
+    catch ( std::bad_alloc& ) {
+      errorText_ = "RtApiJack::probeDeviceOpen: error allocating JackHandle memory.";
+      goto error;
+    }
+
+    if ( pthread_cond_init(&handle->condition, NULL) ) {
+      errorText_ = "RtApiJack::probeDeviceOpen: error initializing pthread condition variable.";
+      goto error;
+    }
+    stream_.apiHandle = (void *) handle;
+    handle->client = client;
+  }
+  handle->deviceName[mode] = deviceName;
+
+  // Allocate necessary internal buffers.
+  unsigned long bufferBytes;
+  bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
+  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
+  if ( stream_.userBuffer[mode] == NULL ) {
+    errorText_ = "RtApiJack::probeDeviceOpen: error allocating user buffer memory.";
+    goto error;
+  }
+
+  if ( stream_.doConvertBuffer[mode] ) {
+
+    bool makeBuffer = true;
+    if ( mode == OUTPUT )
+      bufferBytes = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
+    else { // mode == INPUT
+      bufferBytes = stream_.nDeviceChannels[1] * formatBytes( stream_.deviceFormat[1] );
+      if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
+        unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes(stream_.deviceFormat[0]);
+        if ( bufferBytes < bytesOut ) makeBuffer = false;
+      }
+    }
+
+    if ( makeBuffer ) {
+      bufferBytes *= *bufferSize;
+      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
+      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
+      if ( stream_.deviceBuffer == NULL ) {
+        errorText_ = "RtApiJack::probeDeviceOpen: error allocating device buffer memory.";
+        goto error;
+      }
+    }
+  }
+
+  // Allocate memory for the Jack ports (channels) identifiers.
+  handle->ports[mode] = (jack_port_t **) malloc ( sizeof (jack_port_t *) * channels );
+  if ( handle->ports[mode] == NULL )  {
+    errorText_ = "RtApiJack::probeDeviceOpen: error allocating port memory.";
+    goto error;
+  }
+
+  stream_.device[mode] = device;
+  stream_.channelOffset[mode] = firstChannel;
+  stream_.state = STREAM_STOPPED;
+  stream_.callbackInfo.object = (void *) this;
+
+  if ( stream_.mode == OUTPUT && mode == INPUT )
+    // We had already set up the stream for output.
+    stream_.mode = DUPLEX;
+  else {
+    stream_.mode = mode;
+    jack_set_process_callback( handle->client, jackCallbackHandler, (void *) &stream_.callbackInfo );
+    jack_set_xrun_callback( handle->client, jackXrun, (void *) &handle );
+    jack_on_shutdown( handle->client, jackShutdown, (void *) &stream_.callbackInfo );
+  }
+
+  // Register our ports.
+  char label[64];
+  if ( mode == OUTPUT ) {
+    for ( unsigned int i=0; i<stream_.nUserChannels[0]; i++ ) {
+      snprintf( label, 64, "outport %d", i );
+      handle->ports[0][i] = jack_port_register( handle->client, (const char *)label,
+                                                JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );
+    }
+  }
+  else {
+    for ( unsigned int i=0; i<stream_.nUserChannels[1]; i++ ) {
+      snprintf( label, 64, "inport %d", i );
+      handle->ports[1][i] = jack_port_register( handle->client, (const char *)label,
+                                                JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 );
+    }
+  }
+
+  // Setup the buffer conversion information structure.  We don't use
+  // buffers to do channel offsets, so we override that parameter
+  // here.
+  if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, 0 );
+
+  return SUCCESS;
+
+ error:
+  if ( handle ) {
+    pthread_cond_destroy( &handle->condition );
+    jack_client_close( handle->client );
+
+    if ( handle->ports[0] ) free( handle->ports[0] );
+    if ( handle->ports[1] ) free( handle->ports[1] );
+
+    delete handle;
+    stream_.apiHandle = 0;
+  }
+
+  for ( int i=0; i<2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  return FAILURE;
+}
+
+void RtApiJack :: closeStream( void )
+{
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiJack::closeStream(): no open stream to close!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  JackHandle *handle = (JackHandle *) stream_.apiHandle;
+  if ( handle ) {
+
+    if ( stream_.state == STREAM_RUNNING )
+      jack_deactivate( handle->client );
+
+    jack_client_close( handle->client );
+  }
+
+  if ( handle ) {
+    if ( handle->ports[0] ) free( handle->ports[0] );
+    if ( handle->ports[1] ) free( handle->ports[1] );
+    pthread_cond_destroy( &handle->condition );
+    delete handle;
+    stream_.apiHandle = 0;
+  }
+
+  for ( int i=0; i<2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  stream_.mode = UNINITIALIZED;
+  stream_.state = STREAM_CLOSED;
+}
+
+void RtApiJack :: startStream( void )
+{
+  verifyStream();
+  if ( stream_.state == STREAM_RUNNING ) {
+    errorText_ = "RtApiJack::startStream(): the stream is already running!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  JackHandle *handle = (JackHandle *) stream_.apiHandle;
+  int result = jack_activate( handle->client );
+  if ( result ) {
+    errorText_ = "RtApiJack::startStream(): unable to activate JACK client!";
+    goto unlock;
+  }
+
+  const char **ports;
+
+  // Get the list of available ports.
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+    result = 1;
+    ports = jack_get_ports( handle->client, handle->deviceName[0].c_str(), NULL, JackPortIsInput);
+    if ( ports == NULL) {
+      errorText_ = "RtApiJack::startStream(): error determining available JACK input ports!";
+      goto unlock;
+    }
+
+    // Now make the port connections.  Since RtAudio wasn't designed to
+    // allow the user to select particular channels of a device, we'll
+    // just open the first "nChannels" ports with offset.
+    for ( unsigned int i=0; i<stream_.nUserChannels[0]; i++ ) {
+      result = 1;
+      if ( ports[ stream_.channelOffset[0] + i ] )
+        result = jack_connect( handle->client, jack_port_name( handle->ports[0][i] ), ports[ stream_.channelOffset[0] + i ] );
+      if ( result ) {
+        free( ports );
+        errorText_ = "RtApiJack::startStream(): error connecting output ports!";
+        goto unlock;
+      }
+    }
+    free(ports);
+  }
+
+  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
+    result = 1;
+    ports = jack_get_ports( handle->client, handle->deviceName[1].c_str(), NULL, JackPortIsOutput );
+    if ( ports == NULL) {
+      errorText_ = "RtApiJack::startStream(): error determining available JACK output ports!";
+      goto unlock;
+    }
+
+    // Now make the port connections.  See note above.
+    for ( unsigned int i=0; i<stream_.nUserChannels[1]; i++ ) {
+      result = 1;
+      if ( ports[ stream_.channelOffset[1] + i ] )
+        result = jack_connect( handle->client, ports[ stream_.channelOffset[1] + i ], jack_port_name( handle->ports[1][i] ) );
+      if ( result ) {
+        free( ports );
+        errorText_ = "RtApiJack::startStream(): error connecting input ports!";
+        goto unlock;
+      }
+    }
+    free(ports);
+  }
+
+  handle->drainCounter = 0;
+  handle->internalDrain = false;
+  stream_.state = STREAM_RUNNING;
+
+ unlock:
+  if ( result == 0 ) return;
+  error( RtAudioError::SYSTEM_ERROR );
+}
+
+void RtApiJack :: stopStream( void )
+{
+  verifyStream();
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiJack::stopStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  JackHandle *handle = (JackHandle *) stream_.apiHandle;
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+
+    if ( handle->drainCounter == 0 ) {
+      handle->drainCounter = 2;
+      pthread_cond_wait( &handle->condition, &stream_.mutex ); // block until signaled
+    }
+  }
+
+  jack_deactivate( handle->client );
+  stream_.state = STREAM_STOPPED;
+}
+
+void RtApiJack :: abortStream( void )
+{
+  verifyStream();
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiJack::abortStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  JackHandle *handle = (JackHandle *) stream_.apiHandle;
+  handle->drainCounter = 2;
+
+  stopStream();
+}
+
+// This function will be called by a spawned thread when the user
+// callback function signals that the stream should be stopped or
+// aborted.  It is necessary to handle it this way because the
+// callbackEvent() function must return before the jack_deactivate()
+// function will return.
+static void *jackStopStream( void *ptr )
+{
+  CallbackInfo *info = (CallbackInfo *) ptr;
+  RtApiJack *object = (RtApiJack *) info->object;
+
+  object->stopStream();
+  pthread_exit( NULL );
+}
+
+bool RtApiJack :: callbackEvent( unsigned long nframes )
+{
+  if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS;
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!";
+    error( RtAudioError::WARNING );
+    return FAILURE;
+  }
+  if ( stream_.bufferSize != nframes ) {
+    errorText_ = "RtApiCore::callbackEvent(): the JACK buffer size has changed ... cannot process!";
+    error( RtAudioError::WARNING );
+    return FAILURE;
+  }
+
+  CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
+  JackHandle *handle = (JackHandle *) stream_.apiHandle;
+
+  // Check if we were draining the stream and signal is finished.
+  if ( handle->drainCounter > 3 ) {
+    ThreadHandle threadId;
+
+    stream_.state = STREAM_STOPPING;
+    if ( handle->internalDrain == true )
+      pthread_create( &threadId, NULL, jackStopStream, info );
+    else
+      pthread_cond_signal( &handle->condition );
+    return SUCCESS;
+  }
+
+  // Invoke user callback first, to get fresh output data.
+  if ( handle->drainCounter == 0 ) {
+    RtAudioCallback callback = (RtAudioCallback) info->callback;
+    double streamTime = getStreamTime();
+    RtAudioStreamStatus status = 0;
+    if ( stream_.mode != INPUT && handle->xrun[0] == true ) {
+      status |= RTAUDIO_OUTPUT_UNDERFLOW;
+      handle->xrun[0] = false;
+    }
+    if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) {
+      status |= RTAUDIO_INPUT_OVERFLOW;
+      handle->xrun[1] = false;
+    }
+    int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
+                                  stream_.bufferSize, streamTime, status, info->userData );
+    if ( cbReturnValue == 2 ) {
+      stream_.state = STREAM_STOPPING;
+      handle->drainCounter = 2;
+      ThreadHandle id;
+      pthread_create( &id, NULL, jackStopStream, info );
+      return SUCCESS;
+    }
+    else if ( cbReturnValue == 1 ) {
+      handle->drainCounter = 1;
+      handle->internalDrain = true;
+    }
+  }
+
+  jack_default_audio_sample_t *jackbuffer;
+  unsigned long bufferBytes = nframes * sizeof( jack_default_audio_sample_t );
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+
+    if ( handle->drainCounter > 1 ) { // write zeros to the output stream
+
+      for ( unsigned int i=0; i<stream_.nDeviceChannels[0]; i++ ) {
+        jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[0][i], (jack_nframes_t) nframes );
+        memset( jackbuffer, 0, bufferBytes );
+      }
+
+    }
+    else if ( stream_.doConvertBuffer[0] ) {
+
+      convertBuffer( stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0] );
+
+      for ( unsigned int i=0; i<stream_.nDeviceChannels[0]; i++ ) {
+        jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[0][i], (jack_nframes_t) nframes );
+        memcpy( jackbuffer, &stream_.deviceBuffer[i*bufferBytes], bufferBytes );
+      }
+    }
+    else { // no buffer conversion
+      for ( unsigned int i=0; i<stream_.nUserChannels[0]; i++ ) {
+        jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[0][i], (jack_nframes_t) nframes );
+        memcpy( jackbuffer, &stream_.userBuffer[0][i*bufferBytes], bufferBytes );
+      }
+    }
+  }
+
+  // Don't bother draining input
+  if ( handle->drainCounter ) {
+    handle->drainCounter++;
+    goto unlock;
+  }
+
+  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
+
+    if ( stream_.doConvertBuffer[1] ) {
+      for ( unsigned int i=0; i<stream_.nDeviceChannels[1]; i++ ) {
+        jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[1][i], (jack_nframes_t) nframes );
+        memcpy( &stream_.deviceBuffer[i*bufferBytes], jackbuffer, bufferBytes );
+      }
+      convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
+    }
+    else { // no buffer conversion
+      for ( unsigned int i=0; i<stream_.nUserChannels[1]; i++ ) {
+        jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[1][i], (jack_nframes_t) nframes );
+        memcpy( &stream_.userBuffer[1][i*bufferBytes], jackbuffer, bufferBytes );
+      }
+    }
+  }
+
+ unlock:
+  RtApi::tickStreamTime();
+  return SUCCESS;
+}
+  //******************** End of __UNIX_JACK__ *********************//
+#endif
+
+#if defined(__WINDOWS_ASIO__) // ASIO API on Windows
+
+// The ASIO API is designed around a callback scheme, so this
+// implementation is similar to that used for OS-X CoreAudio and Linux
+// Jack.  The primary constraint with ASIO is that it only allows
+// access to a single driver at a time.  Thus, it is not possible to
+// have more than one simultaneous RtAudio stream.
+//
+// This implementation also requires a number of external ASIO files
+// and a few global variables.  The ASIO callback scheme does not
+// allow for the passing of user data, so we must create a global
+// pointer to our callbackInfo structure.
+//
+// On unix systems, we make use of a pthread condition variable.
+// Since there is no equivalent in Windows, I hacked something based
+// on information found in
+// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html.
+
+#include "asiosys.h"
+#include "asio.h"
+#include "iasiothiscallresolver.h"
+#include "asiodrivers.h"
+#include <cmath>
+
+static AsioDrivers drivers;
+static ASIOCallbacks asioCallbacks;
+static ASIODriverInfo driverInfo;
+static CallbackInfo *asioCallbackInfo;
+static bool asioXRun;
+
+struct AsioHandle {
+  int drainCounter;       // Tracks callback counts when draining
+  bool internalDrain;     // Indicates if stop is initiated from callback or not.
+  ASIOBufferInfo *bufferInfos;
+  HANDLE condition;
+
+  AsioHandle()
+    :drainCounter(0), internalDrain(false), bufferInfos(0) {}
+};
+
+// Function declarations (definitions at end of section)
+static const char* getAsioErrorString( ASIOError result );
+static void sampleRateChanged( ASIOSampleRate sRate );
+static long asioMessages( long selector, long value, void* message, double* opt );
+
+RtApiAsio :: RtApiAsio()
+{
+  // ASIO cannot run on a multi-threaded appartment. You can call
+  // CoInitialize beforehand, but it must be for appartment threading
+  // (in which case, CoInitilialize will return S_FALSE here).
+  coInitialized_ = false;
+  HRESULT hr = CoInitialize( NULL ); 
+  if ( FAILED(hr) ) {
+    errorText_ = "RtApiAsio::ASIO requires a single-threaded appartment. Call CoInitializeEx(0,COINIT_APARTMENTTHREADED)";
+    error( RtAudioError::WARNING );
+  }
+  coInitialized_ = true;
+
+  drivers.removeCurrentDriver();
+  driverInfo.asioVersion = 2;
+
+  // See note in DirectSound implementation about GetDesktopWindow().
+  driverInfo.sysRef = GetForegroundWindow();
+}
+
+RtApiAsio :: ~RtApiAsio()
+{
+  if ( stream_.state != STREAM_CLOSED ) closeStream();
+  if ( coInitialized_ ) CoUninitialize();
+}
+
+unsigned int RtApiAsio :: getDeviceCount( void )
+{
+  return (unsigned int) drivers.asioGetNumDev();
+}
+
+RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device )
+{
+  RtAudio::DeviceInfo info;
+  info.probed = false;
+
+  // Get device ID
+  unsigned int nDevices = getDeviceCount();
+  if ( nDevices == 0 ) {
+    errorText_ = "RtApiAsio::getDeviceInfo: no devices found!";
+    error( RtAudioError::INVALID_USE );
+    return info;
+  }
+
+  if ( device >= nDevices ) {
+    errorText_ = "RtApiAsio::getDeviceInfo: device ID is invalid!";
+    error( RtAudioError::INVALID_USE );
+    return info;
+  }
+
+  // If a stream is already open, we cannot probe other devices.  Thus, use the saved results.
+  if ( stream_.state != STREAM_CLOSED ) {
+    if ( device >= devices_.size() ) {
+      errorText_ = "RtApiAsio::getDeviceInfo: device ID was not present before stream was opened.";
+      error( RtAudioError::WARNING );
+      return info;
+    }
+    return devices_[ device ];
+  }
+
+  char driverName[32];
+  ASIOError result = drivers.asioGetDriverName( (int) device, driverName, 32 );
+  if ( result != ASE_OK ) {
+    errorStream_ << "RtApiAsio::getDeviceInfo: unable to get driver name (" << getAsioErrorString( result ) << ").";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  info.name = driverName;
+
+  if ( !drivers.loadDriver( driverName ) ) {
+    errorStream_ << "RtApiAsio::getDeviceInfo: unable to load driver (" << driverName << ").";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  result = ASIOInit( &driverInfo );
+  if ( result != ASE_OK ) {
+    errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString( result ) << ") initializing driver (" << driverName << ").";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // Determine the device channel information.
+  long inputChannels, outputChannels;
+  result = ASIOGetChannels( &inputChannels, &outputChannels );
+  if ( result != ASE_OK ) {
+    drivers.removeCurrentDriver();
+    errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ").";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  info.outputChannels = outputChannels;
+  info.inputChannels = inputChannels;
+  if ( info.outputChannels > 0 && info.inputChannels > 0 )
+    info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
+
+  // Determine the supported sample rates.
+  info.sampleRates.clear();
+  for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) {
+    result = ASIOCanSampleRate( (ASIOSampleRate) SAMPLE_RATES[i] );
+    if ( result == ASE_OK )
+      info.sampleRates.push_back( SAMPLE_RATES[i] );
+  }
+
+  // Determine supported data types ... just check first channel and assume rest are the same.
+  ASIOChannelInfo channelInfo;
+  channelInfo.channel = 0;
+  channelInfo.isInput = true;
+  if ( info.inputChannels <= 0 ) channelInfo.isInput = false;
+  result = ASIOGetChannelInfo( &channelInfo );
+  if ( result != ASE_OK ) {
+    drivers.removeCurrentDriver();
+    errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString( result ) << ") getting driver channel info (" << driverName << ").";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  info.nativeFormats = 0;
+  if ( channelInfo.type == ASIOSTInt16MSB || channelInfo.type == ASIOSTInt16LSB )
+    info.nativeFormats |= RTAUDIO_SINT16;
+  else if ( channelInfo.type == ASIOSTInt32MSB || channelInfo.type == ASIOSTInt32LSB )
+    info.nativeFormats |= RTAUDIO_SINT32;
+  else if ( channelInfo.type == ASIOSTFloat32MSB || channelInfo.type == ASIOSTFloat32LSB )
+    info.nativeFormats |= RTAUDIO_FLOAT32;
+  else if ( channelInfo.type == ASIOSTFloat64MSB || channelInfo.type == ASIOSTFloat64LSB )
+    info.nativeFormats |= RTAUDIO_FLOAT64;
+  else if ( channelInfo.type == ASIOSTInt24MSB || channelInfo.type == ASIOSTInt24LSB )
+    info.nativeFormats |= RTAUDIO_SINT24;
+
+  if ( info.outputChannels > 0 )
+    if ( getDefaultOutputDevice() == device ) info.isDefaultOutput = true;
+  if ( info.inputChannels > 0 )
+    if ( getDefaultInputDevice() == device ) info.isDefaultInput = true;
+
+  info.probed = true;
+  drivers.removeCurrentDriver();
+  return info;
+}
+
+static void bufferSwitch( long index, ASIOBool /*processNow*/ )
+{
+  RtApiAsio *object = (RtApiAsio *) asioCallbackInfo->object;
+  object->callbackEvent( index );
+}
+
+void RtApiAsio :: saveDeviceInfo( void )
+{
+  devices_.clear();
+
+  unsigned int nDevices = getDeviceCount();
+  devices_.resize( nDevices );
+  for ( unsigned int i=0; i<nDevices; i++ )
+    devices_[i] = getDeviceInfo( i );
+}
+
+bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
+                                   unsigned int firstChannel, unsigned int sampleRate,
+                                   RtAudioFormat format, unsigned int *bufferSize,
+                                   RtAudio::StreamOptions *options )
+{
+  // For ASIO, a duplex stream MUST use the same driver.
+  if ( mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] != device ) {
+    errorText_ = "RtApiAsio::probeDeviceOpen: an ASIO duplex stream must use the same device for input and output!";
+    return FAILURE;
+  }
+
+  char driverName[32];
+  ASIOError result = drivers.asioGetDriverName( (int) device, driverName, 32 );
+  if ( result != ASE_OK ) {
+    errorStream_ << "RtApiAsio::probeDeviceOpen: unable to get driver name (" << getAsioErrorString( result ) << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Only load the driver once for duplex stream.
+  if ( mode != INPUT || stream_.mode != OUTPUT ) {
+    // The getDeviceInfo() function will not work when a stream is open
+    // because ASIO does not allow multiple devices to run at the same
+    // time.  Thus, we'll probe the system before opening a stream and
+    // save the results for use by getDeviceInfo().
+    this->saveDeviceInfo();
+
+    if ( !drivers.loadDriver( driverName ) ) {
+      errorStream_ << "RtApiAsio::probeDeviceOpen: unable to load driver (" << driverName << ").";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    result = ASIOInit( &driverInfo );
+    if ( result != ASE_OK ) {
+      errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") initializing driver (" << driverName << ").";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+  }
+
+  // Check the device channel count.
+  long inputChannels, outputChannels;
+  result = ASIOGetChannels( &inputChannels, &outputChannels );
+  if ( result != ASE_OK ) {
+    drivers.removeCurrentDriver();
+    errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  if ( ( mode == OUTPUT && (channels+firstChannel) > (unsigned int) outputChannels) ||
+       ( mode == INPUT && (channels+firstChannel) > (unsigned int) inputChannels) ) {
+    drivers.removeCurrentDriver();
+    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << channels << ") + offset (" << firstChannel << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+  stream_.nDeviceChannels[mode] = channels;
+  stream_.nUserChannels[mode] = channels;
+  stream_.channelOffset[mode] = firstChannel;
+
+  // Verify the sample rate is supported.
+  result = ASIOCanSampleRate( (ASIOSampleRate) sampleRate );
+  if ( result != ASE_OK ) {
+    drivers.removeCurrentDriver();
+    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << sampleRate << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Get the current sample rate
+  ASIOSampleRate currentRate;
+  result = ASIOGetSampleRate( &currentRate );
+  if ( result != ASE_OK ) {
+    drivers.removeCurrentDriver();
+    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate.";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Set the sample rate only if necessary
+  if ( currentRate != sampleRate ) {
+    result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate );
+    if ( result != ASE_OK ) {
+      drivers.removeCurrentDriver();
+      errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ").";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+  }
+
+  // Determine the driver data type.
+  ASIOChannelInfo channelInfo;
+  channelInfo.channel = 0;
+  if ( mode == OUTPUT ) channelInfo.isInput = false;
+  else channelInfo.isInput = true;
+  result = ASIOGetChannelInfo( &channelInfo );
+  if ( result != ASE_OK ) {
+    drivers.removeCurrentDriver();
+    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting data format.";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Assuming WINDOWS host is always little-endian.
+  stream_.doByteSwap[mode] = false;
+  stream_.userFormat = format;
+  stream_.deviceFormat[mode] = 0;
+  if ( channelInfo.type == ASIOSTInt16MSB || channelInfo.type == ASIOSTInt16LSB ) {
+    stream_.deviceFormat[mode] = RTAUDIO_SINT16;
+    if ( channelInfo.type == ASIOSTInt16MSB ) stream_.doByteSwap[mode] = true;
+  }
+  else if ( channelInfo.type == ASIOSTInt32MSB || channelInfo.type == ASIOSTInt32LSB ) {
+    stream_.deviceFormat[mode] = RTAUDIO_SINT32;
+    if ( channelInfo.type == ASIOSTInt32MSB ) stream_.doByteSwap[mode] = true;
+  }
+  else if ( channelInfo.type == ASIOSTFloat32MSB || channelInfo.type == ASIOSTFloat32LSB ) {
+    stream_.deviceFormat[mode] = RTAUDIO_FLOAT32;
+    if ( channelInfo.type == ASIOSTFloat32MSB ) stream_.doByteSwap[mode] = true;
+  }
+  else if ( channelInfo.type == ASIOSTFloat64MSB || channelInfo.type == ASIOSTFloat64LSB ) {
+    stream_.deviceFormat[mode] = RTAUDIO_FLOAT64;
+    if ( channelInfo.type == ASIOSTFloat64MSB ) stream_.doByteSwap[mode] = true;
+  }
+  else if ( channelInfo.type == ASIOSTInt24MSB || channelInfo.type == ASIOSTInt24LSB ) {
+    stream_.deviceFormat[mode] = RTAUDIO_SINT24;
+    if ( channelInfo.type == ASIOSTInt24MSB ) stream_.doByteSwap[mode] = true;
+  }
+
+  if ( stream_.deviceFormat[mode] == 0 ) {
+    drivers.removeCurrentDriver();
+    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio.";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Set the buffer size.  For a duplex stream, this will end up
+  // setting the buffer size based on the input constraints, which
+  // should be ok.
+  long minSize, maxSize, preferSize, granularity;
+  result = ASIOGetBufferSize( &minSize, &maxSize, &preferSize, &granularity );
+  if ( result != ASE_OK ) {
+    drivers.removeCurrentDriver();
+    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting buffer size.";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
+  else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
+  else if ( granularity == -1 ) {
+    // Make sure bufferSize is a power of two.
+    int log2_of_min_size = 0;
+    int log2_of_max_size = 0;
+
+    for ( unsigned int i = 0; i < sizeof(long) * 8; i++ ) {
+      if ( minSize & ((long)1 << i) ) log2_of_min_size = i;
+      if ( maxSize & ((long)1 << i) ) log2_of_max_size = i;
+    }
+
+    long min_delta = std::abs( (long)*bufferSize - ((long)1 << log2_of_min_size) );
+    int min_delta_num = log2_of_min_size;
+
+    for (int i = log2_of_min_size + 1; i <= log2_of_max_size; i++) {
+      long current_delta = std::abs( (long)*bufferSize - ((long)1 << i) );
+      if (current_delta < min_delta) {
+        min_delta = current_delta;
+        min_delta_num = i;
+      }
+    }
+
+    *bufferSize = ( (unsigned int)1 << min_delta_num );
+    if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
+    else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
+  }
+  else if ( granularity != 0 ) {
+    // Set to an even multiple of granularity, rounding up.
+    *bufferSize = (*bufferSize + granularity-1) / granularity * granularity;
+  }
+
+  if ( mode == INPUT && stream_.mode == OUTPUT && stream_.bufferSize != *bufferSize ) {
+    drivers.removeCurrentDriver();
+    errorText_ = "RtApiAsio::probeDeviceOpen: input/output buffersize discrepancy!";
+    return FAILURE;
+  }
+
+  stream_.bufferSize = *bufferSize;
+  stream_.nBuffers = 2;
+
+  if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
+  else stream_.userInterleaved = true;
+
+  // ASIO always uses non-interleaved buffers.
+  stream_.deviceInterleaved[mode] = false;
+
+  // Allocate, if necessary, our AsioHandle structure for the stream.
+  AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
+  if ( handle == 0 ) {
+    try {
+      handle = new AsioHandle;
+    }
+    catch ( std::bad_alloc& ) {
+      //if ( handle == NULL ) {    
+      drivers.removeCurrentDriver();
+      errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory.";
+      return FAILURE;
+    }
+    handle->bufferInfos = 0;
+
+    // Create a manual-reset event.
+    handle->condition = CreateEvent( NULL,   // no security
+                                     TRUE,   // manual-reset
+                                     FALSE,  // non-signaled initially
+                                     NULL ); // unnamed
+    stream_.apiHandle = (void *) handle;
+  }
+
+  // Create the ASIO internal buffers.  Since RtAudio sets up input
+  // and output separately, we'll have to dispose of previously
+  // created output buffers for a duplex stream.
+  long inputLatency, outputLatency;
+  if ( mode == INPUT && stream_.mode == OUTPUT ) {
+    ASIODisposeBuffers();
+    if ( handle->bufferInfos ) free( handle->bufferInfos );
+  }
+
+  // Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure.
+  bool buffersAllocated = false;
+  unsigned int i, nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
+  handle->bufferInfos = (ASIOBufferInfo *) malloc( nChannels * sizeof(ASIOBufferInfo) );
+  if ( handle->bufferInfos == NULL ) {
+    errorStream_ << "RtApiAsio::probeDeviceOpen: error allocating bufferInfo memory for driver (" << driverName << ").";
+    errorText_ = errorStream_.str();
+    goto error;
+  }
+
+  ASIOBufferInfo *infos;
+  infos = handle->bufferInfos;
+  for ( i=0; i<stream_.nDeviceChannels[0]; i++, infos++ ) {
+    infos->isInput = ASIOFalse;
+    infos->channelNum = i + stream_.channelOffset[0];
+    infos->buffers[0] = infos->buffers[1] = 0;
+  }
+  for ( i=0; i<stream_.nDeviceChannels[1]; i++, infos++ ) {
+    infos->isInput = ASIOTrue;
+    infos->channelNum = i + stream_.channelOffset[1];
+    infos->buffers[0] = infos->buffers[1] = 0;
+  }
+
+  // Set up the ASIO callback structure and create the ASIO data buffers.
+  asioCallbacks.bufferSwitch = &bufferSwitch;
+  asioCallbacks.sampleRateDidChange = &sampleRateChanged;
+  asioCallbacks.asioMessage = &asioMessages;
+  asioCallbacks.bufferSwitchTimeInfo = NULL;
+  result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );
+  if ( result != ASE_OK ) {
+    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers.";
+    errorText_ = errorStream_.str();
+    goto error;
+  }
+  buffersAllocated = true;
+
+  // Set flags for buffer conversion.
+  stream_.doConvertBuffer[mode] = false;
+  if ( stream_.userFormat != stream_.deviceFormat[mode] )
+    stream_.doConvertBuffer[mode] = true;
+  if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
+       stream_.nUserChannels[mode] > 1 )
+    stream_.doConvertBuffer[mode] = true;
+
+  // Allocate necessary internal buffers
+  unsigned long bufferBytes;
+  bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
+  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
+  if ( stream_.userBuffer[mode] == NULL ) {
+    errorText_ = "RtApiAsio::probeDeviceOpen: error allocating user buffer memory.";
+    goto error;
+  }
+
+  if ( stream_.doConvertBuffer[mode] ) {
+
+    bool makeBuffer = true;
+    bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
+    if ( mode == INPUT ) {
+      if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
+        unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
+        if ( bufferBytes <= bytesOut ) makeBuffer = false;
+      }
+    }
+
+    if ( makeBuffer ) {
+      bufferBytes *= *bufferSize;
+      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
+      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
+      if ( stream_.deviceBuffer == NULL ) {
+        errorText_ = "RtApiAsio::probeDeviceOpen: error allocating device buffer memory.";
+        goto error;
+      }
+    }
+  }
+
+  stream_.sampleRate = sampleRate;
+  stream_.device[mode] = device;
+  stream_.state = STREAM_STOPPED;
+  asioCallbackInfo = &stream_.callbackInfo;
+  stream_.callbackInfo.object = (void *) this;
+  if ( stream_.mode == OUTPUT && mode == INPUT )
+    // We had already set up an output stream.
+    stream_.mode = DUPLEX;
+  else
+    stream_.mode = mode;
+
+  // Determine device latencies
+  result = ASIOGetLatencies( &inputLatency, &outputLatency );
+  if ( result != ASE_OK ) {
+    errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting latency.";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING); // warn but don't fail
+  }
+  else {
+    stream_.latency[0] = outputLatency;
+    stream_.latency[1] = inputLatency;
+  }
+
+  // Setup the buffer conversion information structure.  We don't use
+  // buffers to do channel offsets, so we override that parameter
+  // here.
+  if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, 0 );
+
+  return SUCCESS;
+
+ error:
+  if ( buffersAllocated )
+    ASIODisposeBuffers();
+  drivers.removeCurrentDriver();
+
+  if ( handle ) {
+    CloseHandle( handle->condition );
+    if ( handle->bufferInfos )
+      free( handle->bufferInfos );
+    delete handle;
+    stream_.apiHandle = 0;
+  }
+
+  for ( int i=0; i<2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  return FAILURE;
+}
+
+void RtApiAsio :: closeStream()
+{
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiAsio::closeStream(): no open stream to close!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  if ( stream_.state == STREAM_RUNNING ) {
+    stream_.state = STREAM_STOPPED;
+    ASIOStop();
+  }
+  ASIODisposeBuffers();
+  drivers.removeCurrentDriver();
+
+  AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
+  if ( handle ) {
+    CloseHandle( handle->condition );
+    if ( handle->bufferInfos )
+      free( handle->bufferInfos );
+    delete handle;
+    stream_.apiHandle = 0;
+  }
+
+  for ( int i=0; i<2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  stream_.mode = UNINITIALIZED;
+  stream_.state = STREAM_CLOSED;
+}
+
+bool stopThreadCalled = false;
+
+void RtApiAsio :: startStream()
+{
+  verifyStream();
+  if ( stream_.state == STREAM_RUNNING ) {
+    errorText_ = "RtApiAsio::startStream(): the stream is already running!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
+  ASIOError result = ASIOStart();
+  if ( result != ASE_OK ) {
+    errorStream_ << "RtApiAsio::startStream: error (" << getAsioErrorString( result ) << ") starting device.";
+    errorText_ = errorStream_.str();
+    goto unlock;
+  }
+
+  handle->drainCounter = 0;
+  handle->internalDrain = false;
+  ResetEvent( handle->condition );
+  stream_.state = STREAM_RUNNING;
+  asioXRun = false;
+
+ unlock:
+  stopThreadCalled = false;
+
+  if ( result == ASE_OK ) return;
+  error( RtAudioError::SYSTEM_ERROR );
+}
+
+void RtApiAsio :: stopStream()
+{
+  verifyStream();
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiAsio::stopStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+    if ( handle->drainCounter == 0 ) {
+      handle->drainCounter = 2;
+      WaitForSingleObject( handle->condition, INFINITE );  // block until signaled
+    }
+  }
+
+  stream_.state = STREAM_STOPPED;
+
+  ASIOError result = ASIOStop();
+  if ( result != ASE_OK ) {
+    errorStream_ << "RtApiAsio::stopStream: error (" << getAsioErrorString( result ) << ") stopping device.";
+    errorText_ = errorStream_.str();
+  }
+
+  if ( result == ASE_OK ) return;
+  error( RtAudioError::SYSTEM_ERROR );
+}
+
+void RtApiAsio :: abortStream()
+{
+  verifyStream();
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiAsio::abortStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  // The following lines were commented-out because some behavior was
+  // noted where the device buffers need to be zeroed to avoid
+  // continuing sound, even when the device buffers are completely
+  // disposed.  So now, calling abort is the same as calling stop.
+  // AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
+  // handle->drainCounter = 2;
+  stopStream();
+}
+
+// This function will be called by a spawned thread when the user
+// callback function signals that the stream should be stopped or
+// aborted.  It is necessary to handle it this way because the
+// callbackEvent() function must return before the ASIOStop()
+// function will return.
+static unsigned __stdcall asioStopStream( void *ptr )
+{
+  CallbackInfo *info = (CallbackInfo *) ptr;
+  RtApiAsio *object = (RtApiAsio *) info->object;
+
+  object->stopStream();
+  _endthreadex( 0 );
+  return 0;
+}
+
+bool RtApiAsio :: callbackEvent( long bufferIndex )
+{
+  if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS;
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiAsio::callbackEvent(): the stream is closed ... this shouldn't happen!";
+    error( RtAudioError::WARNING );
+    return FAILURE;
+  }
+
+  CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
+  AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
+
+  // Check if we were draining the stream and signal if finished.
+  if ( handle->drainCounter > 3 ) {
+
+    stream_.state = STREAM_STOPPING;
+    if ( handle->internalDrain == false )
+      SetEvent( handle->condition );
+    else { // spawn a thread to stop the stream
+      unsigned threadId;
+      stream_.callbackInfo.thread = _beginthreadex( NULL, 0, &asioStopStream,
+                                                    &stream_.callbackInfo, 0, &threadId );
+    }
+    return SUCCESS;
+  }
+
+  // Invoke user callback to get fresh output data UNLESS we are
+  // draining stream.
+  if ( handle->drainCounter == 0 ) {
+    RtAudioCallback callback = (RtAudioCallback) info->callback;
+    double streamTime = getStreamTime();
+    RtAudioStreamStatus status = 0;
+    if ( stream_.mode != INPUT && asioXRun == true ) {
+      status |= RTAUDIO_OUTPUT_UNDERFLOW;
+      asioXRun = false;
+    }
+    if ( stream_.mode != OUTPUT && asioXRun == true ) {
+      status |= RTAUDIO_INPUT_OVERFLOW;
+      asioXRun = false;
+    }
+    int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
+                                     stream_.bufferSize, streamTime, status, info->userData );
+    if ( cbReturnValue == 2 ) {
+      stream_.state = STREAM_STOPPING;
+      handle->drainCounter = 2;
+      unsigned threadId;
+      stream_.callbackInfo.thread = _beginthreadex( NULL, 0, &asioStopStream,
+                                                    &stream_.callbackInfo, 0, &threadId );
+      return SUCCESS;
+    }
+    else if ( cbReturnValue == 1 ) {
+      handle->drainCounter = 1;
+      handle->internalDrain = true;
+    }
+  }
+
+  unsigned int nChannels, bufferBytes, i, j;
+  nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+
+    bufferBytes = stream_.bufferSize * formatBytes( stream_.deviceFormat[0] );
+
+    if ( handle->drainCounter > 1 ) { // write zeros to the output stream
+
+      for ( i=0, j=0; i<nChannels; i++ ) {
+        if ( handle->bufferInfos[i].isInput != ASIOTrue )
+          memset( handle->bufferInfos[i].buffers[bufferIndex], 0, bufferBytes );
+      }
+
+    }
+    else if ( stream_.doConvertBuffer[0] ) {
+
+      convertBuffer( stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0] );
+      if ( stream_.doByteSwap[0] )
+        byteSwapBuffer( stream_.deviceBuffer,
+                        stream_.bufferSize * stream_.nDeviceChannels[0],
+                        stream_.deviceFormat[0] );
+
+      for ( i=0, j=0; i<nChannels; i++ ) {
+        if ( handle->bufferInfos[i].isInput != ASIOTrue )
+          memcpy( handle->bufferInfos[i].buffers[bufferIndex],
+                  &stream_.deviceBuffer[j++*bufferBytes], bufferBytes );
+      }
+
+    }
+    else {
+
+      if ( stream_.doByteSwap[0] )
+        byteSwapBuffer( stream_.userBuffer[0],
+                        stream_.bufferSize * stream_.nUserChannels[0],
+                        stream_.userFormat );
+
+      for ( i=0, j=0; i<nChannels; i++ ) {
+        if ( handle->bufferInfos[i].isInput != ASIOTrue )
+          memcpy( handle->bufferInfos[i].buffers[bufferIndex],
+                  &stream_.userBuffer[0][bufferBytes*j++], bufferBytes );
+      }
+
+    }
+  }
+
+  // Don't bother draining input
+  if ( handle->drainCounter ) {
+    handle->drainCounter++;
+    goto unlock;
+  }
+
+  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
+
+    bufferBytes = stream_.bufferSize * formatBytes(stream_.deviceFormat[1]);
+
+    if (stream_.doConvertBuffer[1]) {
+
+      // Always interleave ASIO input data.
+      for ( i=0, j=0; i<nChannels; i++ ) {
+        if ( handle->bufferInfos[i].isInput == ASIOTrue )
+          memcpy( &stream_.deviceBuffer[j++*bufferBytes],
+                  handle->bufferInfos[i].buffers[bufferIndex],
+                  bufferBytes );
+      }
+
+      if ( stream_.doByteSwap[1] )
+        byteSwapBuffer( stream_.deviceBuffer,
+                        stream_.bufferSize * stream_.nDeviceChannels[1],
+                        stream_.deviceFormat[1] );
+      convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
+
+    }
+    else {
+      for ( i=0, j=0; i<nChannels; i++ ) {
+        if ( handle->bufferInfos[i].isInput == ASIOTrue ) {
+          memcpy( &stream_.userBuffer[1][bufferBytes*j++],
+                  handle->bufferInfos[i].buffers[bufferIndex],
+                  bufferBytes );
+        }
+      }
+
+      if ( stream_.doByteSwap[1] )
+        byteSwapBuffer( stream_.userBuffer[1],
+                        stream_.bufferSize * stream_.nUserChannels[1],
+                        stream_.userFormat );
+    }
+  }
+
+ unlock:
+  // The following call was suggested by Malte Clasen.  While the API
+  // documentation indicates it should not be required, some device
+  // drivers apparently do not function correctly without it.
+  ASIOOutputReady();
+
+  RtApi::tickStreamTime();
+  return SUCCESS;
+}
+
+static void sampleRateChanged( ASIOSampleRate sRate )
+{
+  // The ASIO documentation says that this usually only happens during
+  // external sync.  Audio processing is not stopped by the driver,
+  // actual sample rate might not have even changed, maybe only the
+  // sample rate status of an AES/EBU or S/PDIF digital input at the
+  // audio device.
+
+  RtApi *object = (RtApi *) asioCallbackInfo->object;
+  try {
+    object->stopStream();
+  }
+  catch ( RtAudioError &exception ) {
+    std::cerr << "\nRtApiAsio: sampleRateChanged() error (" << exception.getMessage() << ")!\n" << std::endl;
+    return;
+  }
+
+  std::cerr << "\nRtApiAsio: driver reports sample rate changed to " << sRate << " ... stream stopped!!!\n" << std::endl;
+}
+
+static long asioMessages( long selector, long value, void* /*message*/, double* /*opt*/ )
+{
+  long ret = 0;
+
+  switch( selector ) {
+  case kAsioSelectorSupported:
+    if ( value == kAsioResetRequest
+         || value == kAsioEngineVersion
+         || value == kAsioResyncRequest
+         || value == kAsioLatenciesChanged
+         // The following three were added for ASIO 2.0, you don't
+         // necessarily have to support them.
+         || value == kAsioSupportsTimeInfo
+         || value == kAsioSupportsTimeCode
+         || value == kAsioSupportsInputMonitor)
+      ret = 1L;
+    break;
+  case kAsioResetRequest:
+    // Defer the task and perform the reset of the driver during the
+    // next "safe" situation.  You cannot reset the driver right now,
+    // as this code is called from the driver.  Reset the driver is
+    // done by completely destruct is. I.e. ASIOStop(),
+    // ASIODisposeBuffers(), Destruction Afterwards you initialize the
+    // driver again.
+    std::cerr << "\nRtApiAsio: driver reset requested!!!" << std::endl;
+    ret = 1L;
+    break;
+  case kAsioResyncRequest:
+    // This informs the application that the driver encountered some
+    // non-fatal data loss.  It is used for synchronization purposes
+    // of different media.  Added mainly to work around the Win16Mutex
+    // problems in Windows 95/98 with the Windows Multimedia system,
+    // which could lose data because the Mutex was held too long by
+    // another thread.  However a driver can issue it in other
+    // situations, too.
+    // std::cerr << "\nRtApiAsio: driver resync requested!!!" << std::endl;
+    asioXRun = true;
+    ret = 1L;
+    break;
+  case kAsioLatenciesChanged:
+    // This will inform the host application that the drivers were
+    // latencies changed.  Beware, it this does not mean that the
+    // buffer sizes have changed!  You might need to update internal
+    // delay data.
+    std::cerr << "\nRtApiAsio: driver latency may have changed!!!" << std::endl;
+    ret = 1L;
+    break;
+  case kAsioEngineVersion:
+    // Return the supported ASIO version of the host application.  If
+    // a host application does not implement this selector, ASIO 1.0
+    // is assumed by the driver.
+    ret = 2L;
+    break;
+  case kAsioSupportsTimeInfo:
+    // Informs the driver whether the
+    // asioCallbacks.bufferSwitchTimeInfo() callback is supported.
+    // For compatibility with ASIO 1.0 drivers the host application
+    // should always support the "old" bufferSwitch method, too.
+    ret = 0;
+    break;
+  case kAsioSupportsTimeCode:
+    // Informs the driver whether application is interested in time
+    // code info.  If an application does not need to know about time
+    // code, the driver has less work to do.
+    ret = 0;
+    break;
+  }
+  return ret;
+}
+
+static const char* getAsioErrorString( ASIOError result )
+{
+  struct Messages 
+  {
+    ASIOError value;
+    const char*message;
+  };
+
+  static const Messages m[] = 
+    {
+      {   ASE_NotPresent,    "Hardware input or output is not present or available." },
+      {   ASE_HWMalfunction,  "Hardware is malfunctioning." },
+      {   ASE_InvalidParameter, "Invalid input parameter." },
+      {   ASE_InvalidMode,      "Invalid mode." },
+      {   ASE_SPNotAdvancing,     "Sample position not advancing." },
+      {   ASE_NoClock,            "Sample clock or rate cannot be determined or is not present." },
+      {   ASE_NoMemory,           "Not enough memory to complete the request." }
+    };
+
+  for ( unsigned int i = 0; i < sizeof(m)/sizeof(m[0]); ++i )
+    if ( m[i].value == result ) return m[i].message;
+
+  return "Unknown error.";
+}
+
+//******************** End of __WINDOWS_ASIO__ *********************//
+#endif
+
+
+#if defined(__WINDOWS_WASAPI__) // Windows WASAPI API
+
+// Authored by Marcus Tomlinson <themarcustomlinson@gmail.com>, April 2014
+// - Introduces support for the Windows WASAPI API
+// - Aims to deliver bit streams to and from hardware at the lowest possible latency, via the absolute minimum buffer sizes required
+// - Provides flexible stream configuration to an otherwise strict and inflexible WASAPI interface
+// - Includes automatic internal conversion of sample rate and buffer size between hardware and the user
+
+#ifndef INITGUID
+  #define INITGUID
+#endif
+#include <audioclient.h>
+#include <avrt.h>
+#include <mmdeviceapi.h>
+#include <functiondiscoverykeys_devpkey.h>
+
+//=============================================================================
+
+#define SAFE_RELEASE( objectPtr )\
+if ( objectPtr )\
+{\
+  objectPtr->Release();\
+  objectPtr = NULL;\
+}
+
+typedef HANDLE ( __stdcall *TAvSetMmThreadCharacteristicsPtr )( LPCWSTR TaskName, LPDWORD TaskIndex );
+
+//-----------------------------------------------------------------------------
+
+// WASAPI dictates stream sample rate, format, channel count, and in some cases, buffer size.
+// Therefore we must perform all necessary conversions to user buffers in order to satisfy these
+// requirements. WasapiBuffer ring buffers are used between HwIn->UserIn and UserOut->HwOut to
+// provide intermediate storage for read / write synchronization.
+class WasapiBuffer
+{
+public:
+  WasapiBuffer()
+    : buffer_( NULL ),
+      bufferSize_( 0 ),
+      inIndex_( 0 ),
+      outIndex_( 0 ) {}
+
+  ~WasapiBuffer() {
+    delete buffer_;
+  }
+
+  // sets the length of the internal ring buffer
+  void setBufferSize( unsigned int bufferSize, unsigned int formatBytes ) {
+    delete buffer_;
+
+    buffer_ = ( char* ) calloc( bufferSize, formatBytes );
+
+    bufferSize_ = bufferSize;
+    inIndex_ = 0;
+    outIndex_ = 0;
+  }
+
+  // attempt to push a buffer into the ring buffer at the current "in" index
+  bool pushBuffer( char* buffer, unsigned int bufferSize, RtAudioFormat format )
+  {
+    if ( !buffer ||                 // incoming buffer is NULL
+         bufferSize == 0 ||         // incoming buffer has no data
+         bufferSize > bufferSize_ ) // incoming buffer too large
+    {
+      return false;
+    }
+
+    unsigned int relOutIndex = outIndex_;
+    unsigned int inIndexEnd = inIndex_ + bufferSize;
+    if ( relOutIndex < inIndex_ && inIndexEnd >= bufferSize_ ) {
+      relOutIndex += bufferSize_;
+    }
+
+    // "in" index can end on the "out" index but cannot begin at it
+    if ( inIndex_ <= relOutIndex && inIndexEnd > relOutIndex ) {
+      return false; // not enough space between "in" index and "out" index
+    }
+
+    // copy buffer from external to internal
+    int fromZeroSize = inIndex_ + bufferSize - bufferSize_;
+    fromZeroSize = fromZeroSize < 0 ? 0 : fromZeroSize;
+    int fromInSize = bufferSize - fromZeroSize;
+
+    switch( format )
+      {
+      case RTAUDIO_SINT8:
+        memcpy( &( ( char* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( char ) );
+        memcpy( buffer_, &( ( char* ) buffer )[fromInSize], fromZeroSize * sizeof( char ) );
+        break;
+      case RTAUDIO_SINT16:
+        memcpy( &( ( short* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( short ) );
+        memcpy( buffer_, &( ( short* ) buffer )[fromInSize], fromZeroSize * sizeof( short ) );
+        break;
+      case RTAUDIO_SINT24:
+        memcpy( &( ( S24* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( S24 ) );
+        memcpy( buffer_, &( ( S24* ) buffer )[fromInSize], fromZeroSize * sizeof( S24 ) );
+        break;
+      case RTAUDIO_SINT32:
+        memcpy( &( ( int* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( int ) );
+        memcpy( buffer_, &( ( int* ) buffer )[fromInSize], fromZeroSize * sizeof( int ) );
+        break;
+      case RTAUDIO_FLOAT32:
+        memcpy( &( ( float* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( float ) );
+        memcpy( buffer_, &( ( float* ) buffer )[fromInSize], fromZeroSize * sizeof( float ) );
+        break;
+      case RTAUDIO_FLOAT64:
+        memcpy( &( ( double* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( double ) );
+        memcpy( buffer_, &( ( double* ) buffer )[fromInSize], fromZeroSize * sizeof( double ) );
+        break;
+    }
+
+    // update "in" index
+    inIndex_ += bufferSize;
+    inIndex_ %= bufferSize_;
+
+    return true;
+  }
+
+  // attempt to pull a buffer from the ring buffer from the current "out" index
+  bool pullBuffer( char* buffer, unsigned int bufferSize, RtAudioFormat format )
+  {
+    if ( !buffer ||                 // incoming buffer is NULL
+         bufferSize == 0 ||         // incoming buffer has no data
+         bufferSize > bufferSize_ ) // incoming buffer too large
+    {
+      return false;
+    }
+
+    unsigned int relInIndex = inIndex_;
+    unsigned int outIndexEnd = outIndex_ + bufferSize;
+    if ( relInIndex < outIndex_ && outIndexEnd >= bufferSize_ ) {
+      relInIndex += bufferSize_;
+    }
+
+    // "out" index can begin at and end on the "in" index
+    if ( outIndex_ < relInIndex && outIndexEnd > relInIndex ) {
+      return false; // not enough space between "out" index and "in" index
+    }
+
+    // copy buffer from internal to external
+    int fromZeroSize = outIndex_ + bufferSize - bufferSize_;
+    fromZeroSize = fromZeroSize < 0 ? 0 : fromZeroSize;
+    int fromOutSize = bufferSize - fromZeroSize;
+
+    switch( format )
+    {
+      case RTAUDIO_SINT8:
+        memcpy( buffer, &( ( char* ) buffer_ )[outIndex_], fromOutSize * sizeof( char ) );
+        memcpy( &( ( char* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( char ) );
+        break;
+      case RTAUDIO_SINT16:
+        memcpy( buffer, &( ( short* ) buffer_ )[outIndex_], fromOutSize * sizeof( short ) );
+        memcpy( &( ( short* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( short ) );
+        break;
+      case RTAUDIO_SINT24:
+        memcpy( buffer, &( ( S24* ) buffer_ )[outIndex_], fromOutSize * sizeof( S24 ) );
+        memcpy( &( ( S24* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( S24 ) );
+        break;
+      case RTAUDIO_SINT32:
+        memcpy( buffer, &( ( int* ) buffer_ )[outIndex_], fromOutSize * sizeof( int ) );
+        memcpy( &( ( int* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( int ) );
+        break;
+      case RTAUDIO_FLOAT32:
+        memcpy( buffer, &( ( float* ) buffer_ )[outIndex_], fromOutSize * sizeof( float ) );
+        memcpy( &( ( float* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( float ) );
+        break;
+      case RTAUDIO_FLOAT64:
+        memcpy( buffer, &( ( double* ) buffer_ )[outIndex_], fromOutSize * sizeof( double ) );
+        memcpy( &( ( double* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( double ) );
+        break;
+    }
+
+    // update "out" index
+    outIndex_ += bufferSize;
+    outIndex_ %= bufferSize_;
+
+    return true;
+  }
+
+private:
+  char* buffer_;
+  unsigned int bufferSize_;
+  unsigned int inIndex_;
+  unsigned int outIndex_;
+};
+
+//-----------------------------------------------------------------------------
+
+// In order to satisfy WASAPI's buffer requirements, we need a means of converting sample rate
+// between HW and the user. The convertBufferWasapi function is used to perform this conversion
+// between HwIn->UserIn and UserOut->HwOut during the stream callback loop.
+// This sample rate converter favors speed over quality, and works best with conversions between
+// one rate and its multiple.
+void convertBufferWasapi( char* outBuffer,
+                          const char* inBuffer,
+                          const unsigned int& channelCount,
+                          const unsigned int& inSampleRate,
+                          const unsigned int& outSampleRate,
+                          const unsigned int& inSampleCount,
+                          unsigned int& outSampleCount,
+                          const RtAudioFormat& format )
+{
+  // calculate the new outSampleCount and relative sampleStep
+  float sampleRatio = ( float ) outSampleRate / inSampleRate;
+  float sampleStep = 1.0f / sampleRatio;
+  float inSampleFraction = 0.0f;
+
+  outSampleCount = ( unsigned int ) ( inSampleCount * sampleRatio );
+
+  // frame-by-frame, copy each relative input sample into it's corresponding output sample
+  for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ )
+  {
+    unsigned int inSample = ( unsigned int ) inSampleFraction;
+
+    switch ( format )
+    {
+      case RTAUDIO_SINT8:
+        memcpy( &( ( char* ) outBuffer )[ outSample * channelCount ], &( ( char* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( char ) );
+        break;
+      case RTAUDIO_SINT16:
+        memcpy( &( ( short* ) outBuffer )[ outSample * channelCount ], &( ( short* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( short ) );
+        break;
+      case RTAUDIO_SINT24:
+        memcpy( &( ( S24* ) outBuffer )[ outSample * channelCount ], &( ( S24* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( S24 ) );
+        break;
+      case RTAUDIO_SINT32:
+        memcpy( &( ( int* ) outBuffer )[ outSample * channelCount ], &( ( int* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( int ) );
+        break;
+      case RTAUDIO_FLOAT32:
+        memcpy( &( ( float* ) outBuffer )[ outSample * channelCount ], &( ( float* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( float ) );
+        break;
+      case RTAUDIO_FLOAT64:
+        memcpy( &( ( double* ) outBuffer )[ outSample * channelCount ], &( ( double* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( double ) );
+        break;
+    }
+
+    // jump to next in sample
+    inSampleFraction += sampleStep;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+// A structure to hold various information related to the WASAPI implementation.
+struct WasapiHandle
+{
+  IAudioClient* captureAudioClient;
+  IAudioClient* renderAudioClient;
+  IAudioCaptureClient* captureClient;
+  IAudioRenderClient* renderClient;
+  HANDLE captureEvent;
+  HANDLE renderEvent;
+
+  WasapiHandle()
+  : captureAudioClient( NULL ),
+    renderAudioClient( NULL ),
+    captureClient( NULL ),
+    renderClient( NULL ),
+    captureEvent( NULL ),
+    renderEvent( NULL ) {}
+};
+
+//=============================================================================
+
+RtApiWasapi::RtApiWasapi()
+  : coInitialized_( false ), deviceEnumerator_( NULL )
+{
+  // WASAPI can run either apartment or multi-threaded
+  HRESULT hr = CoInitialize( NULL );
+  if ( !FAILED( hr ) )
+    coInitialized_ = true;
+
+  // Instantiate device enumerator
+  hr = CoCreateInstance( __uuidof( MMDeviceEnumerator ), NULL,
+                         CLSCTX_ALL, __uuidof( IMMDeviceEnumerator ),
+                         ( void** ) &deviceEnumerator_ );
+
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::RtApiWasapi: Unable to instantiate device enumerator";
+    error( RtAudioError::DRIVER_ERROR );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+RtApiWasapi::~RtApiWasapi()
+{
+  if ( stream_.state != STREAM_CLOSED )
+    closeStream();
+
+  SAFE_RELEASE( deviceEnumerator_ );
+
+  // If this object previously called CoInitialize()
+  if ( coInitialized_ )
+    CoUninitialize();
+}
+
+//=============================================================================
+
+unsigned int RtApiWasapi::getDeviceCount( void )
+{
+  unsigned int captureDeviceCount = 0;
+  unsigned int renderDeviceCount = 0;
+
+  IMMDeviceCollection* captureDevices = NULL;
+  IMMDeviceCollection* renderDevices = NULL;
+
+  // Count capture devices
+  errorText_.clear();
+  HRESULT hr = deviceEnumerator_->EnumAudioEndpoints( eCapture, DEVICE_STATE_ACTIVE, &captureDevices );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve capture device collection.";
+    goto Exit;
+  }
+
+  hr = captureDevices->GetCount( &captureDeviceCount );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve capture device count.";
+    goto Exit;
+  }
+
+  // Count render devices
+  hr = deviceEnumerator_->EnumAudioEndpoints( eRender, DEVICE_STATE_ACTIVE, &renderDevices );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve render device collection.";
+    goto Exit;
+  }
+
+  hr = renderDevices->GetCount( &renderDeviceCount );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve render device count.";
+    goto Exit;
+  }
+
+Exit:
+  // release all references
+  SAFE_RELEASE( captureDevices );
+  SAFE_RELEASE( renderDevices );
+
+  if ( errorText_.empty() )
+    return captureDeviceCount + renderDeviceCount;
+
+  error( RtAudioError::DRIVER_ERROR );
+  return 0;
+}
+
+//-----------------------------------------------------------------------------
+
+RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
+{
+  RtAudio::DeviceInfo info;
+  unsigned int captureDeviceCount = 0;
+  unsigned int renderDeviceCount = 0;
+  std::wstring deviceName;
+  std::string defaultDeviceName;
+  bool isCaptureDevice = false;
+
+  PROPVARIANT deviceNameProp;
+  PROPVARIANT defaultDeviceNameProp;
+
+  IMMDeviceCollection* captureDevices = NULL;
+  IMMDeviceCollection* renderDevices = NULL;
+  IMMDevice* devicePtr = NULL;
+  IMMDevice* defaultDevicePtr = NULL;
+  IAudioClient* audioClient = NULL;
+  IPropertyStore* devicePropStore = NULL;
+  IPropertyStore* defaultDevicePropStore = NULL;
+
+  WAVEFORMATEX* deviceFormat = NULL;
+  WAVEFORMATEX* closestMatchFormat = NULL;
+
+  // probed
+  info.probed = false;
+
+  // Count capture devices
+  errorText_.clear();
+  RtAudioError::Type errorType = RtAudioError::DRIVER_ERROR;
+  HRESULT hr = deviceEnumerator_->EnumAudioEndpoints( eCapture, DEVICE_STATE_ACTIVE, &captureDevices );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve capture device collection.";
+    goto Exit;
+  }
+
+  hr = captureDevices->GetCount( &captureDeviceCount );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve capture device count.";
+    goto Exit;
+  }
+
+  // Count render devices
+  hr = deviceEnumerator_->EnumAudioEndpoints( eRender, DEVICE_STATE_ACTIVE, &renderDevices );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve render device collection.";
+    goto Exit;
+  }
+
+  hr = renderDevices->GetCount( &renderDeviceCount );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve render device count.";
+    goto Exit;
+  }
+
+  // validate device index
+  if ( device >= captureDeviceCount + renderDeviceCount ) {
+    errorText_ = "RtApiWasapi::getDeviceInfo: Invalid device index.";
+    errorType = RtAudioError::INVALID_USE;
+    goto Exit;
+  }
+
+  // determine whether index falls within capture or render devices
+  if ( device >= renderDeviceCount ) {
+    hr = captureDevices->Item( device - renderDeviceCount, &devicePtr );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve capture device handle.";
+      goto Exit;
+    }
+    isCaptureDevice = true;
+  }
+  else {
+    hr = renderDevices->Item( device, &devicePtr );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve render device handle.";
+      goto Exit;
+    }
+    isCaptureDevice = false;
+  }
+
+  // get default device name
+  if ( isCaptureDevice ) {
+    hr = deviceEnumerator_->GetDefaultAudioEndpoint( eCapture, eConsole, &defaultDevicePtr );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve default capture device handle.";
+      goto Exit;
+    }
+  }
+  else {
+    hr = deviceEnumerator_->GetDefaultAudioEndpoint( eRender, eConsole, &defaultDevicePtr );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve default render device handle.";
+      goto Exit;
+    }
+  }
+
+  hr = defaultDevicePtr->OpenPropertyStore( STGM_READ, &defaultDevicePropStore );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to open default device property store.";
+    goto Exit;
+  }
+  PropVariantInit( &defaultDeviceNameProp );
+
+  hr = defaultDevicePropStore->GetValue( PKEY_Device_FriendlyName, &defaultDeviceNameProp );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve default device property: PKEY_Device_FriendlyName.";
+    goto Exit;
+  }
+
+  deviceName = defaultDeviceNameProp.pwszVal;
+  defaultDeviceName = std::string( deviceName.begin(), deviceName.end() );
+
+  // name
+  hr = devicePtr->OpenPropertyStore( STGM_READ, &devicePropStore );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to open device property store.";
+    goto Exit;
+  }
+
+  PropVariantInit( &deviceNameProp );
+
+  hr = devicePropStore->GetValue( PKEY_Device_FriendlyName, &deviceNameProp );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve device property: PKEY_Device_FriendlyName.";
+    goto Exit;
+  }
+
+  deviceName = deviceNameProp.pwszVal;
+  info.name = std::string( deviceName.begin(), deviceName.end() );
+
+  // is default
+  if ( isCaptureDevice ) {
+    info.isDefaultInput = info.name == defaultDeviceName;
+    info.isDefaultOutput = false;
+  }
+  else {
+    info.isDefaultInput = false;
+    info.isDefaultOutput = info.name == defaultDeviceName;
+  }
+
+  // channel count
+  hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL, NULL, ( void** ) &audioClient );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve device audio client.";
+    goto Exit;
+  }
+
+  hr = audioClient->GetMixFormat( &deviceFormat );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve device mix format.";
+    goto Exit;
+  }
+
+  if ( isCaptureDevice ) {
+    info.inputChannels = deviceFormat->nChannels;
+    info.outputChannels = 0;
+    info.duplexChannels = 0;
+  }
+  else {
+    info.inputChannels = 0;
+    info.outputChannels = deviceFormat->nChannels;
+    info.duplexChannels = 0;
+  }
+
+  // sample rates
+  info.sampleRates.clear();
+
+  // allow support for all sample rates as we have a built-in sample rate converter
+  for ( unsigned int i = 0; i < MAX_SAMPLE_RATES; i++ ) {
+    info.sampleRates.push_back( SAMPLE_RATES[i] );
+  }
+
+  // native format
+  info.nativeFormats = 0;
+
+  if ( deviceFormat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
+       ( deviceFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+         ( ( WAVEFORMATEXTENSIBLE* ) deviceFormat )->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT ) )
+  {
+    if ( deviceFormat->wBitsPerSample == 32 ) {
+      info.nativeFormats |= RTAUDIO_FLOAT32;
+    }
+    else if ( deviceFormat->wBitsPerSample == 64 ) {
+      info.nativeFormats |= RTAUDIO_FLOAT64;
+    }
+  }
+  else if ( deviceFormat->wFormatTag == WAVE_FORMAT_PCM ||
+           ( deviceFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+             ( ( WAVEFORMATEXTENSIBLE* ) deviceFormat )->SubFormat == KSDATAFORMAT_SUBTYPE_PCM ) )
+  {
+    if ( deviceFormat->wBitsPerSample == 8 ) {
+      info.nativeFormats |= RTAUDIO_SINT8;
+    }
+    else if ( deviceFormat->wBitsPerSample == 16 ) {
+      info.nativeFormats |= RTAUDIO_SINT16;
+    }
+    else if ( deviceFormat->wBitsPerSample == 24 ) {
+      info.nativeFormats |= RTAUDIO_SINT24;
+    }
+    else if ( deviceFormat->wBitsPerSample == 32 ) {
+      info.nativeFormats |= RTAUDIO_SINT32;
+    }
+  }
+
+  // probed
+  info.probed = true;
+
+Exit:
+  // release all references
+  PropVariantClear( &deviceNameProp );
+  PropVariantClear( &defaultDeviceNameProp );
+
+  SAFE_RELEASE( captureDevices );
+  SAFE_RELEASE( renderDevices );
+  SAFE_RELEASE( devicePtr );
+  SAFE_RELEASE( defaultDevicePtr );
+  SAFE_RELEASE( audioClient );
+  SAFE_RELEASE( devicePropStore );
+  SAFE_RELEASE( defaultDevicePropStore );
+
+  CoTaskMemFree( deviceFormat );
+  CoTaskMemFree( closestMatchFormat );
+
+  if ( !errorText_.empty() )
+    error( errorType );
+  return info;
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int RtApiWasapi::getDefaultOutputDevice( void )
+{
+  for ( unsigned int i = 0; i < getDeviceCount(); i++ ) {
+    if ( getDeviceInfo( i ).isDefaultOutput ) {
+      return i;
+    }
+  }
+
+  return 0;
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int RtApiWasapi::getDefaultInputDevice( void )
+{
+  for ( unsigned int i = 0; i < getDeviceCount(); i++ ) {
+    if ( getDeviceInfo( i ).isDefaultInput ) {
+      return i;
+    }
+  }
+
+  return 0;
+}
+
+//-----------------------------------------------------------------------------
+
+void RtApiWasapi::closeStream( void )
+{
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiWasapi::closeStream: No open stream to close.";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  if ( stream_.state != STREAM_STOPPED )
+    stopStream();
+
+  // clean up stream memory
+  SAFE_RELEASE( ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient )
+  SAFE_RELEASE( ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient )
+
+  SAFE_RELEASE( ( ( WasapiHandle* ) stream_.apiHandle )->captureClient )
+  SAFE_RELEASE( ( ( WasapiHandle* ) stream_.apiHandle )->renderClient )
+
+  if ( ( ( WasapiHandle* ) stream_.apiHandle )->captureEvent )
+    CloseHandle( ( ( WasapiHandle* ) stream_.apiHandle )->captureEvent );
+
+  if ( ( ( WasapiHandle* ) stream_.apiHandle )->renderEvent )
+    CloseHandle( ( ( WasapiHandle* ) stream_.apiHandle )->renderEvent );
+
+  delete ( WasapiHandle* ) stream_.apiHandle;
+  stream_.apiHandle = NULL;
+
+  for ( int i = 0; i < 2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  // update stream state
+  stream_.state = STREAM_CLOSED;
+}
+
+//-----------------------------------------------------------------------------
+
+void RtApiWasapi::startStream( void )
+{
+  verifyStream();
+
+  if ( stream_.state == STREAM_RUNNING ) {
+    errorText_ = "RtApiWasapi::startStream: The stream is already running.";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  // update stream state
+  stream_.state = STREAM_RUNNING;
+
+  // create WASAPI stream thread
+  stream_.callbackInfo.thread = ( ThreadHandle ) CreateThread( NULL, 0, runWasapiThread, this, CREATE_SUSPENDED, NULL );
+
+  if ( !stream_.callbackInfo.thread ) {
+    errorText_ = "RtApiWasapi::startStream: Unable to instantiate callback thread.";
+    error( RtAudioError::THREAD_ERROR );
+  }
+  else {
+    SetThreadPriority( ( void* ) stream_.callbackInfo.thread, stream_.callbackInfo.priority );
+    ResumeThread( ( void* ) stream_.callbackInfo.thread );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RtApiWasapi::stopStream( void )
+{
+  verifyStream();
+
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiWasapi::stopStream: The stream is already stopped.";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  // inform stream thread by setting stream state to STREAM_STOPPING
+  stream_.state = STREAM_STOPPING;
+
+  // wait until stream thread is stopped
+  while( stream_.state != STREAM_STOPPED ) {
+    Sleep( 1 );
+  }
+
+  // Wait for the last buffer to play before stopping.
+  Sleep( 1000 * stream_.bufferSize / stream_.sampleRate );
+
+  // stop capture client if applicable
+  if ( ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient ) {
+    HRESULT hr = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient->Stop();
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::stopStream: Unable to stop capture stream.";
+      error( RtAudioError::DRIVER_ERROR );
+      return;
+    }
+  }
+
+  // stop render client if applicable
+  if ( ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient ) {
+    HRESULT hr = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient->Stop();
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::stopStream: Unable to stop render stream.";
+      error( RtAudioError::DRIVER_ERROR );
+      return;
+    }
+  }
+
+  // close thread handle
+  if ( stream_.callbackInfo.thread && !CloseHandle( ( void* ) stream_.callbackInfo.thread ) ) {
+    errorText_ = "RtApiWasapi::stopStream: Unable to close callback thread.";
+    error( RtAudioError::THREAD_ERROR );
+    return;
+  }
+
+  stream_.callbackInfo.thread = (ThreadHandle) NULL;
+}
+
+//-----------------------------------------------------------------------------
+
+void RtApiWasapi::abortStream( void )
+{
+  verifyStream();
+
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiWasapi::abortStream: The stream is already stopped.";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  // inform stream thread by setting stream state to STREAM_STOPPING
+  stream_.state = STREAM_STOPPING;
+
+  // wait until stream thread is stopped
+  while ( stream_.state != STREAM_STOPPED ) {
+    Sleep( 1 );
+  }
+
+  // stop capture client if applicable
+  if ( ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient ) {
+    HRESULT hr = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient->Stop();
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::abortStream: Unable to stop capture stream.";
+      error( RtAudioError::DRIVER_ERROR );
+      return;
+    }
+  }
+
+  // stop render client if applicable
+  if ( ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient ) {
+    HRESULT hr = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient->Stop();
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::abortStream: Unable to stop render stream.";
+      error( RtAudioError::DRIVER_ERROR );
+      return;
+    }
+  }
+
+  // close thread handle
+  if ( stream_.callbackInfo.thread && !CloseHandle( ( void* ) stream_.callbackInfo.thread ) ) {
+    errorText_ = "RtApiWasapi::abortStream: Unable to close callback thread.";
+    error( RtAudioError::THREAD_ERROR );
+    return;
+  }
+
+  stream_.callbackInfo.thread = (ThreadHandle) NULL;
+}
+
+//-----------------------------------------------------------------------------
+
+bool RtApiWasapi::probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
+                                   unsigned int firstChannel, unsigned int sampleRate,
+                                   RtAudioFormat format, unsigned int* bufferSize,
+                                   RtAudio::StreamOptions* options )
+{
+  bool methodResult = FAILURE;
+  unsigned int captureDeviceCount = 0;
+  unsigned int renderDeviceCount = 0;
+
+  IMMDeviceCollection* captureDevices = NULL;
+  IMMDeviceCollection* renderDevices = NULL;
+  IMMDevice* devicePtr = NULL;
+  WAVEFORMATEX* deviceFormat = NULL;
+  unsigned int bufferBytes;
+  stream_.state = STREAM_STOPPED;
+
+  // create API Handle if not already created
+  if ( !stream_.apiHandle )
+    stream_.apiHandle = ( void* ) new WasapiHandle();
+
+  // Count capture devices
+  errorText_.clear();
+  RtAudioError::Type errorType = RtAudioError::DRIVER_ERROR;
+  HRESULT hr = deviceEnumerator_->EnumAudioEndpoints( eCapture, DEVICE_STATE_ACTIVE, &captureDevices );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device collection.";
+    goto Exit;
+  }
+
+  hr = captureDevices->GetCount( &captureDeviceCount );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device count.";
+    goto Exit;
+  }
+
+  // Count render devices
+  hr = deviceEnumerator_->EnumAudioEndpoints( eRender, DEVICE_STATE_ACTIVE, &renderDevices );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device collection.";
+    goto Exit;
+  }
+
+  hr = renderDevices->GetCount( &renderDeviceCount );
+  if ( FAILED( hr ) ) {
+    errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device count.";
+    goto Exit;
+  }
+
+  // validate device index
+  if ( device >= captureDeviceCount + renderDeviceCount ) {
+    errorType = RtAudioError::INVALID_USE;
+    errorText_ = "RtApiWasapi::probeDeviceOpen: Invalid device index.";
+    goto Exit;
+  }
+
+  // determine whether index falls within capture or render devices
+  if ( device >= renderDeviceCount ) {
+    if ( mode != INPUT ) {
+      errorType = RtAudioError::INVALID_USE;
+      errorText_ = "RtApiWasapi::probeDeviceOpen: Capture device selected as output device.";
+      goto Exit;
+    }
+
+    // retrieve captureAudioClient from devicePtr
+    IAudioClient*& captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient;
+
+    hr = captureDevices->Item( device - renderDeviceCount, &devicePtr );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device handle.";
+      goto Exit;
+    }
+
+    hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL,
+                              NULL, ( void** ) &captureAudioClient );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve device audio client.";
+      goto Exit;
+    }
+
+    hr = captureAudioClient->GetMixFormat( &deviceFormat );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve device mix format.";
+      goto Exit;
+    }
+
+    stream_.nDeviceChannels[mode] = deviceFormat->nChannels;
+    captureAudioClient->GetStreamLatency( ( long long* ) &stream_.latency[mode] );
+  }
+  else {
+    if ( mode != OUTPUT ) {
+      errorType = RtAudioError::INVALID_USE;
+      errorText_ = "RtApiWasapi::probeDeviceOpen: Render device selected as input device.";
+      goto Exit;
+    }
+
+    // retrieve renderAudioClient from devicePtr
+    IAudioClient*& renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient;
+
+    hr = renderDevices->Item( device, &devicePtr );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device handle.";
+      goto Exit;
+    }
+
+    hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL,
+                              NULL, ( void** ) &renderAudioClient );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve device audio client.";
+      goto Exit;
+    }
+
+    hr = renderAudioClient->GetMixFormat( &deviceFormat );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve device mix format.";
+      goto Exit;
+    }
+
+    stream_.nDeviceChannels[mode] = deviceFormat->nChannels;
+    renderAudioClient->GetStreamLatency( ( long long* ) &stream_.latency[mode] );
+  }
+
+  // fill stream data
+  if ( ( stream_.mode == OUTPUT && mode == INPUT ) ||
+       ( stream_.mode == INPUT && mode == OUTPUT ) ) {
+    stream_.mode = DUPLEX;
+  }
+  else {
+    stream_.mode = mode;
+  }
+
+  stream_.device[mode] = device;
+  stream_.doByteSwap[mode] = false;
+  stream_.sampleRate = sampleRate;
+  stream_.bufferSize = *bufferSize;
+  stream_.nBuffers = 1;
+  stream_.nUserChannels[mode] = channels;
+  stream_.channelOffset[mode] = firstChannel;
+  stream_.userFormat = format;
+  stream_.deviceFormat[mode] = getDeviceInfo( device ).nativeFormats;
+
+  if ( options && options->flags & RTAUDIO_NONINTERLEAVED )
+    stream_.userInterleaved = false;
+  else
+    stream_.userInterleaved = true;
+  stream_.deviceInterleaved[mode] = true;
+
+  // Set flags for buffer conversion.
+  stream_.doConvertBuffer[mode] = false;
+  if ( stream_.userFormat != stream_.deviceFormat[mode] ||
+       stream_.nUserChannels != stream_.nDeviceChannels )
+    stream_.doConvertBuffer[mode] = true;
+  else if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
+            stream_.nUserChannels[mode] > 1 )
+    stream_.doConvertBuffer[mode] = true;
+
+  if ( stream_.doConvertBuffer[mode] )
+    setConvertInfo( mode, 0 );
+
+  // Allocate necessary internal buffers
+  bufferBytes = stream_.nUserChannels[mode] * stream_.bufferSize * formatBytes( stream_.userFormat );
+
+  stream_.userBuffer[mode] = ( char* ) calloc( bufferBytes, 1 );
+  if ( !stream_.userBuffer[mode] ) {
+    errorType = RtAudioError::MEMORY_ERROR;
+    errorText_ = "RtApiWasapi::probeDeviceOpen: Error allocating user buffer memory.";
+    goto Exit;
+  }
+
+  if ( options && options->flags & RTAUDIO_SCHEDULE_REALTIME )
+    stream_.callbackInfo.priority = 15;
+  else
+    stream_.callbackInfo.priority = 0;
+
+  ///! TODO: RTAUDIO_MINIMIZE_LATENCY // Provide stream buffers directly to callback
+  ///! TODO: RTAUDIO_HOG_DEVICE       // Exclusive mode
+
+  methodResult = SUCCESS;
+
+Exit:
+  //clean up
+  SAFE_RELEASE( captureDevices );
+  SAFE_RELEASE( renderDevices );
+  SAFE_RELEASE( devicePtr );
+  CoTaskMemFree( deviceFormat );
+
+  // if method failed, close the stream
+  if ( methodResult == FAILURE )
+    closeStream();
+
+  if ( !errorText_.empty() )
+    error( errorType );
+  return methodResult;
+}
+
+//=============================================================================
+
+DWORD WINAPI RtApiWasapi::runWasapiThread( void* wasapiPtr )
+{
+  if ( wasapiPtr )
+    ( ( RtApiWasapi* ) wasapiPtr )->wasapiThread();
+
+  return 0;
+}
+
+DWORD WINAPI RtApiWasapi::stopWasapiThread( void* wasapiPtr )
+{
+  if ( wasapiPtr )
+    ( ( RtApiWasapi* ) wasapiPtr )->stopStream();
+
+  return 0;
+}
+
+DWORD WINAPI RtApiWasapi::abortWasapiThread( void* wasapiPtr )
+{
+  if ( wasapiPtr )
+    ( ( RtApiWasapi* ) wasapiPtr )->abortStream();
+
+  return 0;
+}
+
+//-----------------------------------------------------------------------------
+
+void RtApiWasapi::wasapiThread()
+{
+  // as this is a new thread, we must CoInitialize it
+  CoInitialize( NULL );
+
+  HRESULT hr;
+
+  IAudioClient* captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient;
+  IAudioClient* renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient;
+  IAudioCaptureClient* captureClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureClient;
+  IAudioRenderClient* renderClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderClient;
+  HANDLE captureEvent = ( ( WasapiHandle* ) stream_.apiHandle )->captureEvent;
+  HANDLE renderEvent = ( ( WasapiHandle* ) stream_.apiHandle )->renderEvent;
+
+  WAVEFORMATEX* captureFormat = NULL;
+  WAVEFORMATEX* renderFormat = NULL;
+  float captureSrRatio = 0.0f;
+  float renderSrRatio = 0.0f;
+  WasapiBuffer captureBuffer;
+  WasapiBuffer renderBuffer;
+
+  // declare local stream variables
+  RtAudioCallback callback = ( RtAudioCallback ) stream_.callbackInfo.callback;
+  BYTE* streamBuffer = NULL;
+  unsigned long captureFlags = 0;
+  unsigned int bufferFrameCount = 0;
+  unsigned int numFramesPadding = 0;
+  unsigned int convBufferSize = 0;
+  bool callbackPushed = false;
+  bool callbackPulled = false;
+  bool callbackStopped = false;
+  int callbackResult = 0;
+
+  // convBuffer is used to store converted buffers between WASAPI and the user
+  char* convBuffer = NULL;
+  unsigned int convBuffSize = 0;
+  unsigned int deviceBuffSize = 0;
+
+  errorText_.clear();
+  RtAudioError::Type errorType = RtAudioError::DRIVER_ERROR;
+
+  // Attempt to assign "Pro Audio" characteristic to thread
+  HMODULE AvrtDll = LoadLibrary( (LPCTSTR) "AVRT.dll" );
+  if ( AvrtDll ) {
+    DWORD taskIndex = 0;
+    TAvSetMmThreadCharacteristicsPtr AvSetMmThreadCharacteristicsPtr = ( TAvSetMmThreadCharacteristicsPtr ) GetProcAddress( AvrtDll, "AvSetMmThreadCharacteristicsW" );
+    AvSetMmThreadCharacteristicsPtr( L"Pro Audio", &taskIndex );
+    FreeLibrary( AvrtDll );
+  }
+
+  // start capture stream if applicable
+  if ( captureAudioClient ) {
+    hr = captureAudioClient->GetMixFormat( &captureFormat );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve device mix format.";
+      goto Exit;
+    }
+
+    captureSrRatio = ( ( float ) captureFormat->nSamplesPerSec / stream_.sampleRate );
+
+    // initialize capture stream according to desire buffer size
+    float desiredBufferSize = stream_.bufferSize * captureSrRatio;
+    REFERENCE_TIME desiredBufferPeriod = ( REFERENCE_TIME ) ( ( float ) desiredBufferSize * 10000000 / captureFormat->nSamplesPerSec );
+
+    if ( !captureClient ) {
+      hr = captureAudioClient->Initialize( AUDCLNT_SHAREMODE_SHARED,
+                                           AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
+                                           desiredBufferPeriod,
+                                           desiredBufferPeriod,
+                                           captureFormat,
+                                           NULL );
+      if ( FAILED( hr ) ) {
+        errorText_ = "RtApiWasapi::wasapiThread: Unable to initialize capture audio client.";
+        goto Exit;
+      }
+
+      hr = captureAudioClient->GetService( __uuidof( IAudioCaptureClient ),
+                                           ( void** ) &captureClient );
+      if ( FAILED( hr ) ) {
+        errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve capture client handle.";
+        goto Exit;
+      }
+
+      // configure captureEvent to trigger on every available capture buffer
+      captureEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+      if ( !captureEvent ) {
+        errorType = RtAudioError::SYSTEM_ERROR;
+        errorText_ = "RtApiWasapi::wasapiThread: Unable to create capture event.";
+        goto Exit;
+      }
+
+      hr = captureAudioClient->SetEventHandle( captureEvent );
+      if ( FAILED( hr ) ) {
+        errorText_ = "RtApiWasapi::wasapiThread: Unable to set capture event handle.";
+        goto Exit;
+      }
+
+      ( ( WasapiHandle* ) stream_.apiHandle )->captureClient = captureClient;
+      ( ( WasapiHandle* ) stream_.apiHandle )->captureEvent = captureEvent;
+    }
+
+    unsigned int inBufferSize = 0;
+    hr = captureAudioClient->GetBufferSize( &inBufferSize );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::wasapiThread: Unable to get capture buffer size.";
+      goto Exit;
+    }
+
+    // scale outBufferSize according to stream->user sample rate ratio
+    unsigned int outBufferSize = ( unsigned int ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT];
+    inBufferSize *= stream_.nDeviceChannels[INPUT];
+
+    // set captureBuffer size
+    captureBuffer.setBufferSize( inBufferSize + outBufferSize, formatBytes( stream_.deviceFormat[INPUT] ) );
+
+    // reset the capture stream
+    hr = captureAudioClient->Reset();
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::wasapiThread: Unable to reset capture stream.";
+      goto Exit;
+    }
+
+    // start the capture stream
+    hr = captureAudioClient->Start();
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::wasapiThread: Unable to start capture stream.";
+      goto Exit;
+    }
+  }
+
+  // start render stream if applicable
+  if ( renderAudioClient ) {
+    hr = renderAudioClient->GetMixFormat( &renderFormat );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve device mix format.";
+      goto Exit;
+    }
+
+    renderSrRatio = ( ( float ) renderFormat->nSamplesPerSec / stream_.sampleRate );
+
+    // initialize render stream according to desire buffer size
+    float desiredBufferSize = stream_.bufferSize * renderSrRatio;
+    REFERENCE_TIME desiredBufferPeriod = ( REFERENCE_TIME ) ( ( float ) desiredBufferSize * 10000000 / renderFormat->nSamplesPerSec );
+
+    if ( !renderClient ) {
+      hr = renderAudioClient->Initialize( AUDCLNT_SHAREMODE_SHARED,
+                                          AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
+                                          desiredBufferPeriod,
+                                          desiredBufferPeriod,
+                                          renderFormat,
+                                          NULL );
+      if ( FAILED( hr ) ) {
+        errorText_ = "RtApiWasapi::wasapiThread: Unable to initialize render audio client.";
+        goto Exit;
+      }
+
+      hr = renderAudioClient->GetService( __uuidof( IAudioRenderClient ),
+                                          ( void** ) &renderClient );
+      if ( FAILED( hr ) ) {
+        errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve render client handle.";
+        goto Exit;
+      }
+
+      // configure renderEvent to trigger on every available render buffer
+      renderEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+      if ( !renderEvent ) {
+        errorType = RtAudioError::SYSTEM_ERROR;
+        errorText_ = "RtApiWasapi::wasapiThread: Unable to create render event.";
+        goto Exit;
+      }
+
+      hr = renderAudioClient->SetEventHandle( renderEvent );
+      if ( FAILED( hr ) ) {
+        errorText_ = "RtApiWasapi::wasapiThread: Unable to set render event handle.";
+        goto Exit;
+      }
+
+      ( ( WasapiHandle* ) stream_.apiHandle )->renderClient = renderClient;
+      ( ( WasapiHandle* ) stream_.apiHandle )->renderEvent = renderEvent;
+    }
+
+    unsigned int outBufferSize = 0;
+    hr = renderAudioClient->GetBufferSize( &outBufferSize );
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::wasapiThread: Unable to get render buffer size.";
+      goto Exit;
+    }
+
+    // scale inBufferSize according to user->stream sample rate ratio
+    unsigned int inBufferSize = ( unsigned int ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT];
+    outBufferSize *= stream_.nDeviceChannels[OUTPUT];
+
+    // set renderBuffer size
+    renderBuffer.setBufferSize( inBufferSize + outBufferSize, formatBytes( stream_.deviceFormat[OUTPUT] ) );
+
+    // reset the render stream
+    hr = renderAudioClient->Reset();
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::wasapiThread: Unable to reset render stream.";
+      goto Exit;
+    }
+
+    // start the render stream
+    hr = renderAudioClient->Start();
+    if ( FAILED( hr ) ) {
+      errorText_ = "RtApiWasapi::wasapiThread: Unable to start render stream.";
+      goto Exit;
+    }
+  }
+
+  if ( stream_.mode == INPUT ) {
+    convBuffSize = ( size_t ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] );
+    deviceBuffSize = stream_.bufferSize * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] );
+  }
+  else if ( stream_.mode == OUTPUT ) {
+    convBuffSize = ( size_t ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] );
+    deviceBuffSize = stream_.bufferSize * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] );
+  }
+  else if ( stream_.mode == DUPLEX ) {
+    convBuffSize = max( ( size_t ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ),
+                             ( size_t ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) );
+    deviceBuffSize = max( stream_.bufferSize * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ),
+                               stream_.bufferSize * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) );
+  }
+
+  convBuffer = ( char* ) malloc( convBuffSize );
+  stream_.deviceBuffer = ( char* ) malloc( deviceBuffSize );
+  if ( !convBuffer || !stream_.deviceBuffer ) {
+    errorType = RtAudioError::MEMORY_ERROR;
+    errorText_ = "RtApiWasapi::wasapiThread: Error allocating device buffer memory.";
+    goto Exit;
+  }
+
+  // stream process loop
+  while ( stream_.state != STREAM_STOPPING ) {
+    if ( !callbackPulled ) {
+      // Callback Input
+      // ==============
+      // 1. Pull callback buffer from inputBuffer
+      // 2. If 1. was successful: Convert callback buffer to user sample rate and channel count
+      //                          Convert callback buffer to user format
+
+      if ( captureAudioClient ) {
+        // Pull callback buffer from inputBuffer
+        callbackPulled = captureBuffer.pullBuffer( convBuffer,
+                                                   ( unsigned int ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT],
+                                                   stream_.deviceFormat[INPUT] );
+
+        if ( callbackPulled ) {
+          // Convert callback buffer to user sample rate
+          convertBufferWasapi( stream_.deviceBuffer,
+                               convBuffer,
+                               stream_.nDeviceChannels[INPUT],
+                               captureFormat->nSamplesPerSec,
+                               stream_.sampleRate,
+                               ( unsigned int ) ( stream_.bufferSize * captureSrRatio ),
+                               convBufferSize,
+                               stream_.deviceFormat[INPUT] );
+
+          if ( stream_.doConvertBuffer[INPUT] ) {
+            // Convert callback buffer to user format
+            convertBuffer( stream_.userBuffer[INPUT],
+                           stream_.deviceBuffer,
+                           stream_.convertInfo[INPUT] );
+          }
+          else {
+            // no further conversion, simple copy deviceBuffer to userBuffer
+            memcpy( stream_.userBuffer[INPUT],
+                    stream_.deviceBuffer,
+                    stream_.bufferSize * stream_.nUserChannels[INPUT] * formatBytes( stream_.userFormat ) );
+          }
+        }
+      }
+      else {
+        // if there is no capture stream, set callbackPulled flag
+        callbackPulled = true;
+      }
+
+      // Execute Callback
+      // ================
+      // 1. Execute user callback method
+      // 2. Handle return value from callback
+
+      // if callback has not requested the stream to stop
+      if ( callbackPulled && !callbackStopped ) {
+        // Execute user callback method
+        callbackResult = callback( stream_.userBuffer[OUTPUT],
+                                   stream_.userBuffer[INPUT],
+                                   stream_.bufferSize,
+                                   getStreamTime(),
+                                   captureFlags & AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY ? RTAUDIO_INPUT_OVERFLOW : 0,
+                                   stream_.callbackInfo.userData );
+
+        // Handle return value from callback
+        if ( callbackResult == 1 ) {
+          // instantiate a thread to stop this thread
+          HANDLE threadHandle = CreateThread( NULL, 0, stopWasapiThread, this, 0, NULL );
+          if ( !threadHandle ) {
+            errorType = RtAudioError::THREAD_ERROR;
+            errorText_ = "RtApiWasapi::wasapiThread: Unable to instantiate stream stop thread.";
+            goto Exit;
+          }
+          else if ( !CloseHandle( threadHandle ) ) {
+            errorType = RtAudioError::THREAD_ERROR;
+            errorText_ = "RtApiWasapi::wasapiThread: Unable to close stream stop thread handle.";
+            goto Exit;
+          }
+
+          callbackStopped = true;
+        }
+        else if ( callbackResult == 2 ) {
+          // instantiate a thread to stop this thread
+          HANDLE threadHandle = CreateThread( NULL, 0, abortWasapiThread, this, 0, NULL );
+          if ( !threadHandle ) {
+            errorType = RtAudioError::THREAD_ERROR;
+            errorText_ = "RtApiWasapi::wasapiThread: Unable to instantiate stream abort thread.";
+            goto Exit;
+          }
+          else if ( !CloseHandle( threadHandle ) ) {
+            errorType = RtAudioError::THREAD_ERROR;
+            errorText_ = "RtApiWasapi::wasapiThread: Unable to close stream abort thread handle.";
+            goto Exit;
+          }
+
+          callbackStopped = true;
+        }
+      }
+    }
+
+    // Callback Output
+    // ===============
+    // 1. Convert callback buffer to stream format
+    // 2. Convert callback buffer to stream sample rate and channel count
+    // 3. Push callback buffer into outputBuffer
+
+    if ( renderAudioClient && callbackPulled ) {
+      if ( stream_.doConvertBuffer[OUTPUT] ) {
+        // Convert callback buffer to stream format
+        convertBuffer( stream_.deviceBuffer,
+                       stream_.userBuffer[OUTPUT],
+                       stream_.convertInfo[OUTPUT] );
+
+      }
+
+      // Convert callback buffer to stream sample rate
+      convertBufferWasapi( convBuffer,
+                           stream_.deviceBuffer,
+                           stream_.nDeviceChannels[OUTPUT],
+                           stream_.sampleRate,
+                           renderFormat->nSamplesPerSec,
+                           stream_.bufferSize,
+                           convBufferSize,
+                           stream_.deviceFormat[OUTPUT] );
+
+      // Push callback buffer into outputBuffer
+      callbackPushed = renderBuffer.pushBuffer( convBuffer,
+                                                convBufferSize * stream_.nDeviceChannels[OUTPUT],
+                                                stream_.deviceFormat[OUTPUT] );
+    }
+    else {
+      // if there is no render stream, set callbackPushed flag
+      callbackPushed = true;
+    }
+
+    // Stream Capture
+    // ==============
+    // 1. Get capture buffer from stream
+    // 2. Push capture buffer into inputBuffer
+    // 3. If 2. was successful: Release capture buffer
+
+    if ( captureAudioClient ) {
+      // if the callback input buffer was not pulled from captureBuffer, wait for next capture event
+      if ( !callbackPulled ) {
+        WaitForSingleObject( captureEvent, INFINITE );
+      }
+
+      // Get capture buffer from stream
+      hr = captureClient->GetBuffer( &streamBuffer,
+                                     &bufferFrameCount,
+                                     &captureFlags, NULL, NULL );
+      if ( FAILED( hr ) ) {
+        errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve capture buffer.";
+        goto Exit;
+      }
+
+      if ( bufferFrameCount != 0 ) {
+        // Push capture buffer into inputBuffer
+        if ( captureBuffer.pushBuffer( ( char* ) streamBuffer,
+                                       bufferFrameCount * stream_.nDeviceChannels[INPUT],
+                                       stream_.deviceFormat[INPUT] ) )
+        {
+          // Release capture buffer
+          hr = captureClient->ReleaseBuffer( bufferFrameCount );
+          if ( FAILED( hr ) ) {
+            errorText_ = "RtApiWasapi::wasapiThread: Unable to release capture buffer.";
+            goto Exit;
+          }
+        }
+        else
+        {
+          // Inform WASAPI that capture was unsuccessful
+          hr = captureClient->ReleaseBuffer( 0 );
+          if ( FAILED( hr ) ) {
+            errorText_ = "RtApiWasapi::wasapiThread: Unable to release capture buffer.";
+            goto Exit;
+          }
+        }
+      }
+      else
+      {
+        // Inform WASAPI that capture was unsuccessful
+        hr = captureClient->ReleaseBuffer( 0 );
+        if ( FAILED( hr ) ) {
+          errorText_ = "RtApiWasapi::wasapiThread: Unable to release capture buffer.";
+          goto Exit;
+        }
+      }
+    }
+
+    // Stream Render
+    // =============
+    // 1. Get render buffer from stream
+    // 2. Pull next buffer from outputBuffer
+    // 3. If 2. was successful: Fill render buffer with next buffer
+    //                          Release render buffer
+
+    if ( renderAudioClient ) {
+      // if the callback output buffer was not pushed to renderBuffer, wait for next render event
+      if ( callbackPulled && !callbackPushed ) {
+        WaitForSingleObject( renderEvent, INFINITE );
+      }
+
+      // Get render buffer from stream
+      hr = renderAudioClient->GetBufferSize( &bufferFrameCount );
+      if ( FAILED( hr ) ) {
+        errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve render buffer size.";
+        goto Exit;
+      }
+
+      hr = renderAudioClient->GetCurrentPadding( &numFramesPadding );
+      if ( FAILED( hr ) ) {
+        errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve render buffer padding.";
+        goto Exit;
+      }
+
+      bufferFrameCount -= numFramesPadding;
+
+      if ( bufferFrameCount != 0 ) {
+        hr = renderClient->GetBuffer( bufferFrameCount, &streamBuffer );
+        if ( FAILED( hr ) ) {
+          errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve render buffer.";
+          goto Exit;
+        }
+
+        // Pull next buffer from outputBuffer
+        // Fill render buffer with next buffer
+        if ( renderBuffer.pullBuffer( ( char* ) streamBuffer,
+                                      bufferFrameCount * stream_.nDeviceChannels[OUTPUT],
+                                      stream_.deviceFormat[OUTPUT] ) )
+        {
+          // Release render buffer
+          hr = renderClient->ReleaseBuffer( bufferFrameCount, 0 );
+          if ( FAILED( hr ) ) {
+            errorText_ = "RtApiWasapi::wasapiThread: Unable to release render buffer.";
+            goto Exit;
+          }
+        }
+        else
+        {
+          // Inform WASAPI that render was unsuccessful
+          hr = renderClient->ReleaseBuffer( 0, 0 );
+          if ( FAILED( hr ) ) {
+            errorText_ = "RtApiWasapi::wasapiThread: Unable to release render buffer.";
+            goto Exit;
+          }
+        }
+      }
+      else
+      {
+        // Inform WASAPI that render was unsuccessful
+        hr = renderClient->ReleaseBuffer( 0, 0 );
+        if ( FAILED( hr ) ) {
+          errorText_ = "RtApiWasapi::wasapiThread: Unable to release render buffer.";
+          goto Exit;
+        }
+      }
+    }
+
+    // if the callback buffer was pushed renderBuffer reset callbackPulled flag
+    if ( callbackPushed ) {
+      callbackPulled = false;
+    }
+
+    // tick stream time
+    RtApi::tickStreamTime();
+  }
+
+Exit:
+  // clean up
+  CoTaskMemFree( captureFormat );
+  CoTaskMemFree( renderFormat );
+
+  free ( convBuffer );
+
+  CoUninitialize();
+
+  // update stream state
+  stream_.state = STREAM_STOPPED;
+
+  if ( errorText_.empty() )
+    return;
+  else
+    error( errorType );
+}
+
+//******************** End of __WINDOWS_WASAPI__ *********************//
+#endif
+
+
+#if defined(__WINDOWS_DS__) // Windows DirectSound API
+
+// Modified by Robin Davies, October 2005
+// - Improvements to DirectX pointer chasing. 
+// - Bug fix for non-power-of-two Asio granularity used by Edirol PCR-A30.
+// - Auto-call CoInitialize for DSOUND and ASIO platforms.
+// Various revisions for RtAudio 4.0 by Gary Scavone, April 2007
+// Changed device query structure for RtAudio 4.0.7, January 2010
+
+#include <dsound.h>
+#include <assert.h>
+#include <algorithm>
+
+#if defined(__MINGW32__)
+  // missing from latest mingw winapi
+#define WAVE_FORMAT_96M08 0x00010000 /* 96 kHz, Mono, 8-bit */
+#define WAVE_FORMAT_96S08 0x00020000 /* 96 kHz, Stereo, 8-bit */
+#define WAVE_FORMAT_96M16 0x00040000 /* 96 kHz, Mono, 16-bit */
+#define WAVE_FORMAT_96S16 0x00080000 /* 96 kHz, Stereo, 16-bit */
+#endif
+
+#define MINIMUM_DEVICE_BUFFER_SIZE 32768
+
+#ifdef _MSC_VER // if Microsoft Visual C++
+#pragma comment( lib, "winmm.lib" ) // then, auto-link winmm.lib. Otherwise, it has to be added manually.
+#endif
+
+static inline DWORD dsPointerBetween( DWORD pointer, DWORD laterPointer, DWORD earlierPointer, DWORD bufferSize )
+{
+  if ( pointer > bufferSize ) pointer -= bufferSize;
+  if ( laterPointer < earlierPointer ) laterPointer += bufferSize;
+  if ( pointer < earlierPointer ) pointer += bufferSize;
+  return pointer >= earlierPointer && pointer < laterPointer;
+}
+
+// A structure to hold various information related to the DirectSound
+// API implementation.
+struct DsHandle {
+  unsigned int drainCounter; // Tracks callback counts when draining
+  bool internalDrain;        // Indicates if stop is initiated from callback or not.
+  void *id[2];
+  void *buffer[2];
+  bool xrun[2];
+  UINT bufferPointer[2];  
+  DWORD dsBufferSize[2];
+  DWORD dsPointerLeadTime[2]; // the number of bytes ahead of the safe pointer to lead by.
+  HANDLE condition;
+
+  DsHandle()
+    :drainCounter(0), internalDrain(false) { id[0] = 0; id[1] = 0; buffer[0] = 0; buffer[1] = 0; xrun[0] = false; xrun[1] = false; bufferPointer[0] = 0; bufferPointer[1] = 0; }
+};
+
+// Declarations for utility functions, callbacks, and structures
+// specific to the DirectSound implementation.
+static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
+                                          LPCTSTR description,
+                                          LPCTSTR module,
+                                          LPVOID lpContext );
+
+static const char* getErrorString( int code );
+
+static unsigned __stdcall callbackHandler( void *ptr );
+
+struct DsDevice {
+  LPGUID id[2];
+  bool validId[2];
+  bool found;
+  std::string name;
+
+  DsDevice()
+  : found(false) { validId[0] = false; validId[1] = false; }
+};
+
+struct DsProbeData {
+  bool isInput;
+  std::vector<struct DsDevice>* dsDevices;
+};
+
+RtApiDs :: RtApiDs()
+{
+  // Dsound will run both-threaded. If CoInitialize fails, then just
+  // accept whatever the mainline chose for a threading model.
+  coInitialized_ = false;
+  HRESULT hr = CoInitialize( NULL );
+  if ( !FAILED( hr ) ) coInitialized_ = true;
+}
+
+RtApiDs :: ~RtApiDs()
+{
+  if ( coInitialized_ ) CoUninitialize(); // balanced call.
+  if ( stream_.state != STREAM_CLOSED ) closeStream();
+}
+
+// The DirectSound default output is always the first device.
+unsigned int RtApiDs :: getDefaultOutputDevice( void )
+{
+  return 0;
+}
+
+// The DirectSound default input is always the first input device,
+// which is the first capture device enumerated.
+unsigned int RtApiDs :: getDefaultInputDevice( void )
+{
+  return 0;
+}
+
+unsigned int RtApiDs :: getDeviceCount( void )
+{
+  // Set query flag for previously found devices to false, so that we
+  // can check for any devices that have disappeared.
+  for ( unsigned int i=0; i<dsDevices.size(); i++ )
+    dsDevices[i].found = false;
+
+  // Query DirectSound devices.
+  struct DsProbeData probeInfo;
+  probeInfo.isInput = false;
+  probeInfo.dsDevices = &dsDevices;
+  HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &probeInfo );
+  if ( FAILED( result ) ) {
+    errorStream_ << "RtApiDs::getDeviceCount: error (" << getErrorString( result ) << ") enumerating output devices!";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+  }
+
+  // Query DirectSoundCapture devices.
+  probeInfo.isInput = true;
+  result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &probeInfo );
+  if ( FAILED( result ) ) {
+    errorStream_ << "RtApiDs::getDeviceCount: error (" << getErrorString( result ) << ") enumerating input devices!";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+  }
+
+  // Clean out any devices that may have disappeared.
+  std::vector< int > indices;
+  for ( unsigned int i=0; i<dsDevices.size(); i++ )
+    if ( dsDevices[i].found == false ) indices.push_back( i );
+  //unsigned int nErased = 0;
+  for ( unsigned int i=0; i<indices.size(); i++ )
+    dsDevices.erase( dsDevices.begin()+indices[i] );
+  //dsDevices.erase( dsDevices.begin()-nErased++ );
+
+  return static_cast<unsigned int>(dsDevices.size());
+}
+
+RtAudio::DeviceInfo RtApiDs :: getDeviceInfo( unsigned int device )
+{
+  RtAudio::DeviceInfo info;
+  info.probed = false;
+
+  if ( dsDevices.size() == 0 ) {
+    // Force a query of all devices
+    getDeviceCount();
+    if ( dsDevices.size() == 0 ) {
+      errorText_ = "RtApiDs::getDeviceInfo: no devices found!";
+      error( RtAudioError::INVALID_USE );
+      return info;
+    }
+  }
+
+  if ( device >= dsDevices.size() ) {
+    errorText_ = "RtApiDs::getDeviceInfo: device ID is invalid!";
+    error( RtAudioError::INVALID_USE );
+    return info;
+  }
+
+  HRESULT result;
+  if ( dsDevices[ device ].validId[0] == false ) goto probeInput;
+
+  LPDIRECTSOUND output;
+  DSCAPS outCaps;
+  result = DirectSoundCreate( dsDevices[ device ].id[0], &output, NULL );
+  if ( FAILED( result ) ) {
+    errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") opening output device (" << dsDevices[ device ].name << ")!";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    goto probeInput;
+  }
+
+  outCaps.dwSize = sizeof( outCaps );
+  result = output->GetCaps( &outCaps );
+  if ( FAILED( result ) ) {
+    output->Release();
+    errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") getting capabilities!";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    goto probeInput;
+  }
+
+  // Get output channel information.
+  info.outputChannels = ( outCaps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1;
+
+  // Get sample rate information.
+  info.sampleRates.clear();
+  for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
+    if ( SAMPLE_RATES[k] >= (unsigned int) outCaps.dwMinSecondarySampleRate &&
+         SAMPLE_RATES[k] <= (unsigned int) outCaps.dwMaxSecondarySampleRate )
+      info.sampleRates.push_back( SAMPLE_RATES[k] );
+  }
+
+  // Get format information.
+  if ( outCaps.dwFlags & DSCAPS_PRIMARY16BIT ) info.nativeFormats |= RTAUDIO_SINT16;
+  if ( outCaps.dwFlags & DSCAPS_PRIMARY8BIT ) info.nativeFormats |= RTAUDIO_SINT8;
+
+  output->Release();
+
+  if ( getDefaultOutputDevice() == device )
+    info.isDefaultOutput = true;
+
+  if ( dsDevices[ device ].validId[1] == false ) {
+    info.name = dsDevices[ device ].name;
+    info.probed = true;
+    return info;
+  }
+
+ probeInput:
+
+  LPDIRECTSOUNDCAPTURE input;
+  result = DirectSoundCaptureCreate( dsDevices[ device ].id[1], &input, NULL );
+  if ( FAILED( result ) ) {
+    errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") opening input device (" << dsDevices[ device ].name << ")!";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  DSCCAPS inCaps;
+  inCaps.dwSize = sizeof( inCaps );
+  result = input->GetCaps( &inCaps );
+  if ( FAILED( result ) ) {
+    input->Release();
+    errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") getting object capabilities (" << dsDevices[ device ].name << ")!";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // Get input channel information.
+  info.inputChannels = inCaps.dwChannels;
+
+  // Get sample rate and format information.
+  std::vector<unsigned int> rates;
+  if ( inCaps.dwChannels >= 2 ) {
+    if ( inCaps.dwFormats & WAVE_FORMAT_1S16 ) info.nativeFormats |= RTAUDIO_SINT16;
+    if ( inCaps.dwFormats & WAVE_FORMAT_2S16 ) info.nativeFormats |= RTAUDIO_SINT16;
+    if ( inCaps.dwFormats & WAVE_FORMAT_4S16 ) info.nativeFormats |= RTAUDIO_SINT16;
+    if ( inCaps.dwFormats & WAVE_FORMAT_96S16 ) info.nativeFormats |= RTAUDIO_SINT16;
+    if ( inCaps.dwFormats & WAVE_FORMAT_1S08 ) info.nativeFormats |= RTAUDIO_SINT8;
+    if ( inCaps.dwFormats & WAVE_FORMAT_2S08 ) info.nativeFormats |= RTAUDIO_SINT8;
+    if ( inCaps.dwFormats & WAVE_FORMAT_4S08 ) info.nativeFormats |= RTAUDIO_SINT8;
+    if ( inCaps.dwFormats & WAVE_FORMAT_96S08 ) info.nativeFormats |= RTAUDIO_SINT8;
+
+    if ( info.nativeFormats & RTAUDIO_SINT16 ) {
+      if ( inCaps.dwFormats & WAVE_FORMAT_1S16 ) rates.push_back( 11025 );
+      if ( inCaps.dwFormats & WAVE_FORMAT_2S16 ) rates.push_back( 22050 );
+      if ( inCaps.dwFormats & WAVE_FORMAT_4S16 ) rates.push_back( 44100 );
+      if ( inCaps.dwFormats & WAVE_FORMAT_96S16 ) rates.push_back( 96000 );
+    }
+    else if ( info.nativeFormats & RTAUDIO_SINT8 ) {
+      if ( inCaps.dwFormats & WAVE_FORMAT_1S08 ) rates.push_back( 11025 );
+      if ( inCaps.dwFormats & WAVE_FORMAT_2S08 ) rates.push_back( 22050 );
+      if ( inCaps.dwFormats & WAVE_FORMAT_4S08 ) rates.push_back( 44100 );
+      if ( inCaps.dwFormats & WAVE_FORMAT_96S08 ) rates.push_back( 96000 );
+    }
+  }
+  else if ( inCaps.dwChannels == 1 ) {
+    if ( inCaps.dwFormats & WAVE_FORMAT_1M16 ) info.nativeFormats |= RTAUDIO_SINT16;
+    if ( inCaps.dwFormats & WAVE_FORMAT_2M16 ) info.nativeFormats |= RTAUDIO_SINT16;
+    if ( inCaps.dwFormats & WAVE_FORMAT_4M16 ) info.nativeFormats |= RTAUDIO_SINT16;
+    if ( inCaps.dwFormats & WAVE_FORMAT_96M16 ) info.nativeFormats |= RTAUDIO_SINT16;
+    if ( inCaps.dwFormats & WAVE_FORMAT_1M08 ) info.nativeFormats |= RTAUDIO_SINT8;
+    if ( inCaps.dwFormats & WAVE_FORMAT_2M08 ) info.nativeFormats |= RTAUDIO_SINT8;
+    if ( inCaps.dwFormats & WAVE_FORMAT_4M08 ) info.nativeFormats |= RTAUDIO_SINT8;
+    if ( inCaps.dwFormats & WAVE_FORMAT_96M08 ) info.nativeFormats |= RTAUDIO_SINT8;
+
+    if ( info.nativeFormats & RTAUDIO_SINT16 ) {
+      if ( inCaps.dwFormats & WAVE_FORMAT_1M16 ) rates.push_back( 11025 );
+      if ( inCaps.dwFormats & WAVE_FORMAT_2M16 ) rates.push_back( 22050 );
+      if ( inCaps.dwFormats & WAVE_FORMAT_4M16 ) rates.push_back( 44100 );
+      if ( inCaps.dwFormats & WAVE_FORMAT_96M16 ) rates.push_back( 96000 );
+    }
+    else if ( info.nativeFormats & RTAUDIO_SINT8 ) {
+      if ( inCaps.dwFormats & WAVE_FORMAT_1M08 ) rates.push_back( 11025 );
+      if ( inCaps.dwFormats & WAVE_FORMAT_2M08 ) rates.push_back( 22050 );
+      if ( inCaps.dwFormats & WAVE_FORMAT_4M08 ) rates.push_back( 44100 );
+      if ( inCaps.dwFormats & WAVE_FORMAT_96M08 ) rates.push_back( 96000 );
+    }
+  }
+  else info.inputChannels = 0; // technically, this would be an error
+
+  input->Release();
+
+  if ( info.inputChannels == 0 ) return info;
+
+  // Copy the supported rates to the info structure but avoid duplication.
+  bool found;
+  for ( unsigned int i=0; i<rates.size(); i++ ) {
+    found = false;
+    for ( unsigned int j=0; j<info.sampleRates.size(); j++ ) {
+      if ( rates[i] == info.sampleRates[j] ) {
+        found = true;
+        break;
+      }
+    }
+    if ( found == false ) info.sampleRates.push_back( rates[i] );
+  }
+  std::sort( info.sampleRates.begin(), info.sampleRates.end() );
+
+  // If device opens for both playback and capture, we determine the channels.
+  if ( info.outputChannels > 0 && info.inputChannels > 0 )
+    info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
+
+  if ( device == 0 ) info.isDefaultInput = true;
+
+  // Copy name and return.
+  info.name = dsDevices[ device ].name;
+  info.probed = true;
+  return info;
+}
+
+bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
+                                 unsigned int firstChannel, unsigned int sampleRate,
+                                 RtAudioFormat format, unsigned int *bufferSize,
+                                 RtAudio::StreamOptions *options )
+{
+  if ( channels + firstChannel > 2 ) {
+    errorText_ = "RtApiDs::probeDeviceOpen: DirectSound does not support more than 2 channels per device.";
+    return FAILURE;
+  }
+
+  size_t nDevices = dsDevices.size();
+  if ( nDevices == 0 ) {
+    // This should not happen because a check is made before this function is called.
+    errorText_ = "RtApiDs::probeDeviceOpen: no devices found!";
+    return FAILURE;
+  }
+
+  if ( device >= nDevices ) {
+    // This should not happen because a check is made before this function is called.
+    errorText_ = "RtApiDs::probeDeviceOpen: device ID is invalid!";
+    return FAILURE;
+  }
+
+  if ( mode == OUTPUT ) {
+    if ( dsDevices[ device ].validId[0] == false ) {
+      errorStream_ << "RtApiDs::probeDeviceOpen: device (" << device << ") does not support output!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+  }
+  else { // mode == INPUT
+    if ( dsDevices[ device ].validId[1] == false ) {
+      errorStream_ << "RtApiDs::probeDeviceOpen: device (" << device << ") does not support input!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+  }
+
+  // According to a note in PortAudio, using GetDesktopWindow()
+  // instead of GetForegroundWindow() is supposed to avoid problems
+  // that occur when the application's window is not the foreground
+  // window.  Also, if the application window closes before the
+  // DirectSound buffer, DirectSound can crash.  In the past, I had
+  // problems when using GetDesktopWindow() but it seems fine now
+  // (January 2010).  I'll leave it commented here.
+  // HWND hWnd = GetForegroundWindow();
+  HWND hWnd = GetDesktopWindow();
+
+  // Check the numberOfBuffers parameter and limit the lowest value to
+  // two.  This is a judgement call and a value of two is probably too
+  // low for capture, but it should work for playback.
+  int nBuffers = 0;
+  if ( options ) nBuffers = options->numberOfBuffers;
+  if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) nBuffers = 2;
+  if ( nBuffers < 2 ) nBuffers = 3;
+
+  // Check the lower range of the user-specified buffer size and set
+  // (arbitrarily) to a lower bound of 32.
+  if ( *bufferSize < 32 ) *bufferSize = 32;
+
+  // Create the wave format structure.  The data format setting will
+  // be determined later.
+  WAVEFORMATEX waveFormat;
+  ZeroMemory( &waveFormat, sizeof(WAVEFORMATEX) );
+  waveFormat.wFormatTag = WAVE_FORMAT_PCM;
+  waveFormat.nChannels = channels + firstChannel;
+  waveFormat.nSamplesPerSec = (unsigned long) sampleRate;
+
+  // Determine the device buffer size. By default, we'll use the value
+  // defined above (32K), but we will grow it to make allowances for
+  // very large software buffer sizes.
+  DWORD dsBufferSize = MINIMUM_DEVICE_BUFFER_SIZE;
+  DWORD dsPointerLeadTime = 0;
+
+  void *ohandle = 0, *bhandle = 0;
+  HRESULT result;
+  if ( mode == OUTPUT ) {
+
+    LPDIRECTSOUND output;
+    result = DirectSoundCreate( dsDevices[ device ].id[0], &output, NULL );
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") opening output device (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    DSCAPS outCaps;
+    outCaps.dwSize = sizeof( outCaps );
+    result = output->GetCaps( &outCaps );
+    if ( FAILED( result ) ) {
+      output->Release();
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting capabilities (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    // Check channel information.
+    if ( channels + firstChannel == 2 && !( outCaps.dwFlags & DSCAPS_PRIMARYSTEREO ) ) {
+      errorStream_ << "RtApiDs::getDeviceInfo: the output device (" << dsDevices[ device ].name << ") does not support stereo playback.";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    // Check format information.  Use 16-bit format unless not
+    // supported or user requests 8-bit.
+    if ( outCaps.dwFlags & DSCAPS_PRIMARY16BIT &&
+         !( format == RTAUDIO_SINT8 && outCaps.dwFlags & DSCAPS_PRIMARY8BIT ) ) {
+      waveFormat.wBitsPerSample = 16;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT16;
+    }
+    else {
+      waveFormat.wBitsPerSample = 8;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT8;
+    }
+    stream_.userFormat = format;
+
+    // Update wave format structure and buffer information.
+    waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8;
+    waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
+    dsPointerLeadTime = nBuffers * (*bufferSize) * (waveFormat.wBitsPerSample / 8) * channels;
+
+    // If the user wants an even bigger buffer, increase the device buffer size accordingly.
+    while ( dsPointerLeadTime * 2U > dsBufferSize )
+      dsBufferSize *= 2;
+
+    // Set cooperative level to DSSCL_EXCLUSIVE ... sound stops when window focus changes.
+    // result = output->SetCooperativeLevel( hWnd, DSSCL_EXCLUSIVE );
+    // Set cooperative level to DSSCL_PRIORITY ... sound remains when window focus changes.
+    result = output->SetCooperativeLevel( hWnd, DSSCL_PRIORITY );
+    if ( FAILED( result ) ) {
+      output->Release();
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") setting cooperative level (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    // Even though we will write to the secondary buffer, we need to
+    // access the primary buffer to set the correct output format
+    // (since the default is 8-bit, 22 kHz!).  Setup the DS primary
+    // buffer description.
+    DSBUFFERDESC bufferDescription;
+    ZeroMemory( &bufferDescription, sizeof( DSBUFFERDESC ) );
+    bufferDescription.dwSize = sizeof( DSBUFFERDESC );
+    bufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER;
+
+    // Obtain the primary buffer
+    LPDIRECTSOUNDBUFFER buffer;
+    result = output->CreateSoundBuffer( &bufferDescription, &buffer, NULL );
+    if ( FAILED( result ) ) {
+      output->Release();
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") accessing primary buffer (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    // Set the primary DS buffer sound format.
+    result = buffer->SetFormat( &waveFormat );
+    if ( FAILED( result ) ) {
+      output->Release();
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") setting primary buffer format (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    // Setup the secondary DS buffer description.
+    ZeroMemory( &bufferDescription, sizeof( DSBUFFERDESC ) );
+    bufferDescription.dwSize = sizeof( DSBUFFERDESC );
+    bufferDescription.dwFlags = ( DSBCAPS_STICKYFOCUS |
+                                  DSBCAPS_GLOBALFOCUS |
+                                  DSBCAPS_GETCURRENTPOSITION2 |
+                                  DSBCAPS_LOCHARDWARE );  // Force hardware mixing
+    bufferDescription.dwBufferBytes = dsBufferSize;
+    bufferDescription.lpwfxFormat = &waveFormat;
+
+    // Try to create the secondary DS buffer.  If that doesn't work,
+    // try to use software mixing.  Otherwise, there's a problem.
+    result = output->CreateSoundBuffer( &bufferDescription, &buffer, NULL );
+    if ( FAILED( result ) ) {
+      bufferDescription.dwFlags = ( DSBCAPS_STICKYFOCUS |
+                                    DSBCAPS_GLOBALFOCUS |
+                                    DSBCAPS_GETCURRENTPOSITION2 |
+                                    DSBCAPS_LOCSOFTWARE );  // Force software mixing
+      result = output->CreateSoundBuffer( &bufferDescription, &buffer, NULL );
+      if ( FAILED( result ) ) {
+        output->Release();
+        errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") creating secondary buffer (" << dsDevices[ device ].name << ")!";
+        errorText_ = errorStream_.str();
+        return FAILURE;
+      }
+    }
+
+    // Get the buffer size ... might be different from what we specified.
+    DSBCAPS dsbcaps;
+    dsbcaps.dwSize = sizeof( DSBCAPS );
+    result = buffer->GetCaps( &dsbcaps );
+    if ( FAILED( result ) ) {
+      output->Release();
+      buffer->Release();
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting buffer settings (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    dsBufferSize = dsbcaps.dwBufferBytes;
+
+    // Lock the DS buffer
+    LPVOID audioPtr;
+    DWORD dataLen;
+    result = buffer->Lock( 0, dsBufferSize, &audioPtr, &dataLen, NULL, NULL, 0 );
+    if ( FAILED( result ) ) {
+      output->Release();
+      buffer->Release();
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") locking buffer (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    // Zero the DS buffer
+    ZeroMemory( audioPtr, dataLen );
+
+    // Unlock the DS buffer
+    result = buffer->Unlock( audioPtr, dataLen, NULL, 0 );
+    if ( FAILED( result ) ) {
+      output->Release();
+      buffer->Release();
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") unlocking buffer (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    ohandle = (void *) output;
+    bhandle = (void *) buffer;
+  }
+
+  if ( mode == INPUT ) {
+
+    LPDIRECTSOUNDCAPTURE input;
+    result = DirectSoundCaptureCreate( dsDevices[ device ].id[1], &input, NULL );
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") opening input device (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    DSCCAPS inCaps;
+    inCaps.dwSize = sizeof( inCaps );
+    result = input->GetCaps( &inCaps );
+    if ( FAILED( result ) ) {
+      input->Release();
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting input capabilities (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    // Check channel information.
+    if ( inCaps.dwChannels < channels + firstChannel ) {
+      errorText_ = "RtApiDs::getDeviceInfo: the input device does not support requested input channels.";
+      return FAILURE;
+    }
+
+    // Check format information.  Use 16-bit format unless user
+    // requests 8-bit.
+    DWORD deviceFormats;
+    if ( channels + firstChannel == 2 ) {
+      deviceFormats = WAVE_FORMAT_1S08 | WAVE_FORMAT_2S08 | WAVE_FORMAT_4S08 | WAVE_FORMAT_96S08;
+      if ( format == RTAUDIO_SINT8 && inCaps.dwFormats & deviceFormats ) {
+        waveFormat.wBitsPerSample = 8;
+        stream_.deviceFormat[mode] = RTAUDIO_SINT8;
+      }
+      else { // assume 16-bit is supported
+        waveFormat.wBitsPerSample = 16;
+        stream_.deviceFormat[mode] = RTAUDIO_SINT16;
+      }
+    }
+    else { // channel == 1
+      deviceFormats = WAVE_FORMAT_1M08 | WAVE_FORMAT_2M08 | WAVE_FORMAT_4M08 | WAVE_FORMAT_96M08;
+      if ( format == RTAUDIO_SINT8 && inCaps.dwFormats & deviceFormats ) {
+        waveFormat.wBitsPerSample = 8;
+        stream_.deviceFormat[mode] = RTAUDIO_SINT8;
+      }
+      else { // assume 16-bit is supported
+        waveFormat.wBitsPerSample = 16;
+        stream_.deviceFormat[mode] = RTAUDIO_SINT16;
+      }
+    }
+    stream_.userFormat = format;
+
+    // Update wave format structure and buffer information.
+    waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8;
+    waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
+    dsPointerLeadTime = nBuffers * (*bufferSize) * (waveFormat.wBitsPerSample / 8) * channels;
+
+    // If the user wants an even bigger buffer, increase the device buffer size accordingly.
+    while ( dsPointerLeadTime * 2U > dsBufferSize )
+      dsBufferSize *= 2;
+
+    // Setup the secondary DS buffer description.
+    DSCBUFFERDESC bufferDescription;
+    ZeroMemory( &bufferDescription, sizeof( DSCBUFFERDESC ) );
+    bufferDescription.dwSize = sizeof( DSCBUFFERDESC );
+    bufferDescription.dwFlags = 0;
+    bufferDescription.dwReserved = 0;
+    bufferDescription.dwBufferBytes = dsBufferSize;
+    bufferDescription.lpwfxFormat = &waveFormat;
+
+    // Create the capture buffer.
+    LPDIRECTSOUNDCAPTUREBUFFER buffer;
+    result = input->CreateCaptureBuffer( &bufferDescription, &buffer, NULL );
+    if ( FAILED( result ) ) {
+      input->Release();
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") creating input buffer (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    // Get the buffer size ... might be different from what we specified.
+    DSCBCAPS dscbcaps;
+    dscbcaps.dwSize = sizeof( DSCBCAPS );
+    result = buffer->GetCaps( &dscbcaps );
+    if ( FAILED( result ) ) {
+      input->Release();
+      buffer->Release();
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting buffer settings (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    dsBufferSize = dscbcaps.dwBufferBytes;
+
+    // NOTE: We could have a problem here if this is a duplex stream
+    // and the play and capture hardware buffer sizes are different
+    // (I'm actually not sure if that is a problem or not).
+    // Currently, we are not verifying that.
+
+    // Lock the capture buffer
+    LPVOID audioPtr;
+    DWORD dataLen;
+    result = buffer->Lock( 0, dsBufferSize, &audioPtr, &dataLen, NULL, NULL, 0 );
+    if ( FAILED( result ) ) {
+      input->Release();
+      buffer->Release();
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") locking input buffer (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    // Zero the buffer
+    ZeroMemory( audioPtr, dataLen );
+
+    // Unlock the buffer
+    result = buffer->Unlock( audioPtr, dataLen, NULL, 0 );
+    if ( FAILED( result ) ) {
+      input->Release();
+      buffer->Release();
+      errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") unlocking input buffer (" << dsDevices[ device ].name << ")!";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+
+    ohandle = (void *) input;
+    bhandle = (void *) buffer;
+  }
+
+  // Set various stream parameters
+  DsHandle *handle = 0;
+  stream_.nDeviceChannels[mode] = channels + firstChannel;
+  stream_.nUserChannels[mode] = channels;
+  stream_.bufferSize = *bufferSize;
+  stream_.channelOffset[mode] = firstChannel;
+  stream_.deviceInterleaved[mode] = true;
+  if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
+  else stream_.userInterleaved = true;
+
+  // Set flag for buffer conversion
+  stream_.doConvertBuffer[mode] = false;
+  if (stream_.nUserChannels[mode] != stream_.nDeviceChannels[mode])
+    stream_.doConvertBuffer[mode] = true;
+  if (stream_.userFormat != stream_.deviceFormat[mode])
+    stream_.doConvertBuffer[mode] = true;
+  if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
+       stream_.nUserChannels[mode] > 1 )
+    stream_.doConvertBuffer[mode] = true;
+
+  // Allocate necessary internal buffers
+  long bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
+  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
+  if ( stream_.userBuffer[mode] == NULL ) {
+    errorText_ = "RtApiDs::probeDeviceOpen: error allocating user buffer memory.";
+    goto error;
+  }
+
+  if ( stream_.doConvertBuffer[mode] ) {
+
+    bool makeBuffer = true;
+    bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
+    if ( mode == INPUT ) {
+      if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
+        unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
+        if ( bufferBytes <= (long) bytesOut ) makeBuffer = false;
+      }
+    }
+
+    if ( makeBuffer ) {
+      bufferBytes *= *bufferSize;
+      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
+      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
+      if ( stream_.deviceBuffer == NULL ) {
+        errorText_ = "RtApiDs::probeDeviceOpen: error allocating device buffer memory.";
+        goto error;
+      }
+    }
+  }
+
+  // Allocate our DsHandle structures for the stream.
+  if ( stream_.apiHandle == 0 ) {
+    try {
+      handle = new DsHandle;
+    }
+    catch ( std::bad_alloc& ) {
+      errorText_ = "RtApiDs::probeDeviceOpen: error allocating AsioHandle memory.";
+      goto error;
+    }
+
+    // Create a manual-reset event.
+    handle->condition = CreateEvent( NULL,   // no security
+                                     TRUE,   // manual-reset
+                                     FALSE,  // non-signaled initially
+                                     NULL ); // unnamed
+    stream_.apiHandle = (void *) handle;
+  }
+  else
+    handle = (DsHandle *) stream_.apiHandle;
+  handle->id[mode] = ohandle;
+  handle->buffer[mode] = bhandle;
+  handle->dsBufferSize[mode] = dsBufferSize;
+  handle->dsPointerLeadTime[mode] = dsPointerLeadTime;
+
+  stream_.device[mode] = device;
+  stream_.state = STREAM_STOPPED;
+  if ( stream_.mode == OUTPUT && mode == INPUT )
+    // We had already set up an output stream.
+    stream_.mode = DUPLEX;
+  else
+    stream_.mode = mode;
+  stream_.nBuffers = nBuffers;
+  stream_.sampleRate = sampleRate;
+
+  // Setup the buffer conversion information structure.
+  if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel );
+
+  // Setup the callback thread.
+  if ( stream_.callbackInfo.isRunning == false ) {
+    unsigned threadId;
+    stream_.callbackInfo.isRunning = true;
+    stream_.callbackInfo.object = (void *) this;
+    stream_.callbackInfo.thread = _beginthreadex( NULL, 0, &callbackHandler,
+                                                  &stream_.callbackInfo, 0, &threadId );
+    if ( stream_.callbackInfo.thread == 0 ) {
+      errorText_ = "RtApiDs::probeDeviceOpen: error creating callback thread!";
+      goto error;
+    }
+
+    // Boost DS thread priority
+    SetThreadPriority( (HANDLE) stream_.callbackInfo.thread, THREAD_PRIORITY_HIGHEST );
+  }
+  return SUCCESS;
+
+ error:
+  if ( handle ) {
+    if ( handle->buffer[0] ) { // the object pointer can be NULL and valid
+      LPDIRECTSOUND object = (LPDIRECTSOUND) handle->id[0];
+      LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
+      if ( buffer ) buffer->Release();
+      object->Release();
+    }
+    if ( handle->buffer[1] ) {
+      LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE) handle->id[1];
+      LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
+      if ( buffer ) buffer->Release();
+      object->Release();
+    }
+    CloseHandle( handle->condition );
+    delete handle;
+    stream_.apiHandle = 0;
+  }
+
+  for ( int i=0; i<2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  stream_.state = STREAM_CLOSED;
+  return FAILURE;
+}
+
+void RtApiDs :: closeStream()
+{
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiDs::closeStream(): no open stream to close!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  // Stop the callback thread.
+  stream_.callbackInfo.isRunning = false;
+  WaitForSingleObject( (HANDLE) stream_.callbackInfo.thread, INFINITE );
+  CloseHandle( (HANDLE) stream_.callbackInfo.thread );
+
+  DsHandle *handle = (DsHandle *) stream_.apiHandle;
+  if ( handle ) {
+    if ( handle->buffer[0] ) { // the object pointer can be NULL and valid
+      LPDIRECTSOUND object = (LPDIRECTSOUND) handle->id[0];
+      LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
+      if ( buffer ) {
+        buffer->Stop();
+        buffer->Release();
+      }
+      object->Release();
+    }
+    if ( handle->buffer[1] ) {
+      LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE) handle->id[1];
+      LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
+      if ( buffer ) {
+        buffer->Stop();
+        buffer->Release();
+      }
+      object->Release();
+    }
+    CloseHandle( handle->condition );
+    delete handle;
+    stream_.apiHandle = 0;
+  }
+
+  for ( int i=0; i<2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  stream_.mode = UNINITIALIZED;
+  stream_.state = STREAM_CLOSED;
+}
+
+void RtApiDs :: startStream()
+{
+  verifyStream();
+  if ( stream_.state == STREAM_RUNNING ) {
+    errorText_ = "RtApiDs::startStream(): the stream is already running!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  DsHandle *handle = (DsHandle *) stream_.apiHandle;
+
+  // Increase scheduler frequency on lesser windows (a side-effect of
+  // increasing timer accuracy).  On greater windows (Win2K or later),
+  // this is already in effect.
+  timeBeginPeriod( 1 ); 
+
+  buffersRolling = false;
+  duplexPrerollBytes = 0;
+
+  if ( stream_.mode == DUPLEX ) {
+    // 0.5 seconds of silence in DUPLEX mode while the devices spin up and synchronize.
+    duplexPrerollBytes = (int) ( 0.5 * stream_.sampleRate * formatBytes( stream_.deviceFormat[1] ) * stream_.nDeviceChannels[1] );
+  }
+
+  HRESULT result = 0;
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+
+    LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
+    result = buffer->Play( 0, 0, DSBPLAY_LOOPING );
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::startStream: error (" << getErrorString( result ) << ") starting output buffer!";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+  }
+
+  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
+
+    LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
+    result = buffer->Start( DSCBSTART_LOOPING );
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::startStream: error (" << getErrorString( result ) << ") starting input buffer!";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+  }
+
+  handle->drainCounter = 0;
+  handle->internalDrain = false;
+  ResetEvent( handle->condition );
+  stream_.state = STREAM_RUNNING;
+
+ unlock:
+  if ( FAILED( result ) ) error( RtAudioError::SYSTEM_ERROR );
+}
+
+void RtApiDs :: stopStream()
+{
+  verifyStream();
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiDs::stopStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  HRESULT result = 0;
+  LPVOID audioPtr;
+  DWORD dataLen;
+  DsHandle *handle = (DsHandle *) stream_.apiHandle;
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+    if ( handle->drainCounter == 0 ) {
+      handle->drainCounter = 2;
+      WaitForSingleObject( handle->condition, INFINITE );  // block until signaled
+    }
+
+    stream_.state = STREAM_STOPPED;
+
+    MUTEX_LOCK( &stream_.mutex );
+
+    // Stop the buffer and clear memory
+    LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
+    result = buffer->Stop();
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") stopping output buffer!";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+
+    // Lock the buffer and clear it so that if we start to play again,
+    // we won't have old data playing.
+    result = buffer->Lock( 0, handle->dsBufferSize[0], &audioPtr, &dataLen, NULL, NULL, 0 );
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") locking output buffer!";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+
+    // Zero the DS buffer
+    ZeroMemory( audioPtr, dataLen );
+
+    // Unlock the DS buffer
+    result = buffer->Unlock( audioPtr, dataLen, NULL, 0 );
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") unlocking output buffer!";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+
+    // If we start playing again, we must begin at beginning of buffer.
+    handle->bufferPointer[0] = 0;
+  }
+
+  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
+    LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
+    audioPtr = NULL;
+    dataLen = 0;
+
+    stream_.state = STREAM_STOPPED;
+
+    if ( stream_.mode != DUPLEX )
+      MUTEX_LOCK( &stream_.mutex );
+
+    result = buffer->Stop();
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") stopping input buffer!";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+
+    // Lock the buffer and clear it so that if we start to play again,
+    // we won't have old data playing.
+    result = buffer->Lock( 0, handle->dsBufferSize[1], &audioPtr, &dataLen, NULL, NULL, 0 );
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") locking input buffer!";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+
+    // Zero the DS buffer
+    ZeroMemory( audioPtr, dataLen );
+
+    // Unlock the DS buffer
+    result = buffer->Unlock( audioPtr, dataLen, NULL, 0 );
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") unlocking input buffer!";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+
+    // If we start recording again, we must begin at beginning of buffer.
+    handle->bufferPointer[1] = 0;
+  }
+
+ unlock:
+  timeEndPeriod( 1 ); // revert to normal scheduler frequency on lesser windows.
+  MUTEX_UNLOCK( &stream_.mutex );
+
+  if ( FAILED( result ) ) error( RtAudioError::SYSTEM_ERROR );
+}
+
+void RtApiDs :: abortStream()
+{
+  verifyStream();
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiDs::abortStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  DsHandle *handle = (DsHandle *) stream_.apiHandle;
+  handle->drainCounter = 2;
+
+  stopStream();
+}
+
+void RtApiDs :: callbackEvent()
+{
+  if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) {
+    Sleep( 50 ); // sleep 50 milliseconds
+    return;
+  }
+
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiDs::callbackEvent(): the stream is closed ... this shouldn't happen!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
+  DsHandle *handle = (DsHandle *) stream_.apiHandle;
+
+  // Check if we were draining the stream and signal is finished.
+  if ( handle->drainCounter > stream_.nBuffers + 2 ) {
+
+    stream_.state = STREAM_STOPPING;
+    if ( handle->internalDrain == false )
+      SetEvent( handle->condition );
+    else
+      stopStream();
+    return;
+  }
+
+  // Invoke user callback to get fresh output data UNLESS we are
+  // draining stream.
+  if ( handle->drainCounter == 0 ) {
+    RtAudioCallback callback = (RtAudioCallback) info->callback;
+    double streamTime = getStreamTime();
+    RtAudioStreamStatus status = 0;
+    if ( stream_.mode != INPUT && handle->xrun[0] == true ) {
+      status |= RTAUDIO_OUTPUT_UNDERFLOW;
+      handle->xrun[0] = false;
+    }
+    if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) {
+      status |= RTAUDIO_INPUT_OVERFLOW;
+      handle->xrun[1] = false;
+    }
+    int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
+                                  stream_.bufferSize, streamTime, status, info->userData );
+    if ( cbReturnValue == 2 ) {
+      stream_.state = STREAM_STOPPING;
+      handle->drainCounter = 2;
+      abortStream();
+      return;
+    }
+    else if ( cbReturnValue == 1 ) {
+      handle->drainCounter = 1;
+      handle->internalDrain = true;
+    }
+  }
+
+  HRESULT result;
+  DWORD currentWritePointer, safeWritePointer;
+  DWORD currentReadPointer, safeReadPointer;
+  UINT nextWritePointer;
+
+  LPVOID buffer1 = NULL;
+  LPVOID buffer2 = NULL;
+  DWORD bufferSize1 = 0;
+  DWORD bufferSize2 = 0;
+
+  char *buffer;
+  long bufferBytes;
+
+  MUTEX_LOCK( &stream_.mutex );
+  if ( stream_.state == STREAM_STOPPED ) {
+    MUTEX_UNLOCK( &stream_.mutex );
+    return;
+  }
+
+  if ( buffersRolling == false ) {
+    if ( stream_.mode == DUPLEX ) {
+      //assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );
+
+      // It takes a while for the devices to get rolling. As a result,
+      // there's no guarantee that the capture and write device pointers
+      // will move in lockstep.  Wait here for both devices to start
+      // rolling, and then set our buffer pointers accordingly.
+      // e.g. Crystal Drivers: the capture buffer starts up 5700 to 9600
+      // bytes later than the write buffer.
+
+      // Stub: a serious risk of having a pre-emptive scheduling round
+      // take place between the two GetCurrentPosition calls... but I'm
+      // really not sure how to solve the problem.  Temporarily boost to
+      // Realtime priority, maybe; but I'm not sure what priority the
+      // DirectSound service threads run at. We *should* be roughly
+      // within a ms or so of correct.
+
+      LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
+      LPDIRECTSOUNDCAPTUREBUFFER dsCaptureBuffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
+
+      DWORD startSafeWritePointer, startSafeReadPointer;
+
+      result = dsWriteBuffer->GetCurrentPosition( NULL, &startSafeWritePointer );
+      if ( FAILED( result ) ) {
+        errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
+        errorText_ = errorStream_.str();
+        error( RtAudioError::SYSTEM_ERROR );
+        return;
+      }
+      result = dsCaptureBuffer->GetCurrentPosition( NULL, &startSafeReadPointer );
+      if ( FAILED( result ) ) {
+        errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
+        errorText_ = errorStream_.str();
+        error( RtAudioError::SYSTEM_ERROR );
+        return;
+      }
+      while ( true ) {
+        result = dsWriteBuffer->GetCurrentPosition( NULL, &safeWritePointer );
+        if ( FAILED( result ) ) {
+          errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
+          errorText_ = errorStream_.str();
+          error( RtAudioError::SYSTEM_ERROR );
+          return;
+        }
+        result = dsCaptureBuffer->GetCurrentPosition( NULL, &safeReadPointer );
+        if ( FAILED( result ) ) {
+          errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
+          errorText_ = errorStream_.str();
+          error( RtAudioError::SYSTEM_ERROR );
+          return;
+        }
+        if ( safeWritePointer != startSafeWritePointer && safeReadPointer != startSafeReadPointer ) break;
+        Sleep( 1 );
+      }
+
+      //assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );
+
+      handle->bufferPointer[0] = safeWritePointer + handle->dsPointerLeadTime[0];
+      if ( handle->bufferPointer[0] >= handle->dsBufferSize[0] ) handle->bufferPointer[0] -= handle->dsBufferSize[0];
+      handle->bufferPointer[1] = safeReadPointer;
+    }
+    else if ( stream_.mode == OUTPUT ) {
+
+      // Set the proper nextWritePosition after initial startup.
+      LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
+      result = dsWriteBuffer->GetCurrentPosition( &currentWritePointer, &safeWritePointer );
+      if ( FAILED( result ) ) {
+        errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
+        errorText_ = errorStream_.str();
+        error( RtAudioError::SYSTEM_ERROR );
+        return;
+      }
+      handle->bufferPointer[0] = safeWritePointer + handle->dsPointerLeadTime[0];
+      if ( handle->bufferPointer[0] >= handle->dsBufferSize[0] ) handle->bufferPointer[0] -= handle->dsBufferSize[0];
+    }
+
+    buffersRolling = true;
+  }
+
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+    
+    LPDIRECTSOUNDBUFFER dsBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
+
+    if ( handle->drainCounter > 1 ) { // write zeros to the output stream
+      bufferBytes = stream_.bufferSize * stream_.nUserChannels[0];
+      bufferBytes *= formatBytes( stream_.userFormat );
+      memset( stream_.userBuffer[0], 0, bufferBytes );
+    }
+
+    // Setup parameters and do buffer conversion if necessary.
+    if ( stream_.doConvertBuffer[0] ) {
+      buffer = stream_.deviceBuffer;
+      convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] );
+      bufferBytes = stream_.bufferSize * stream_.nDeviceChannels[0];
+      bufferBytes *= formatBytes( stream_.deviceFormat[0] );
+    }
+    else {
+      buffer = stream_.userBuffer[0];
+      bufferBytes = stream_.bufferSize * stream_.nUserChannels[0];
+      bufferBytes *= formatBytes( stream_.userFormat );
+    }
+
+    // No byte swapping necessary in DirectSound implementation.
+
+    // Ahhh ... windoze.  16-bit data is signed but 8-bit data is
+    // unsigned.  So, we need to convert our signed 8-bit data here to
+    // unsigned.
+    if ( stream_.deviceFormat[0] == RTAUDIO_SINT8 )
+      for ( int i=0; i<bufferBytes; i++ ) buffer[i] = (unsigned char) ( buffer[i] + 128 );
+
+    DWORD dsBufferSize = handle->dsBufferSize[0];
+    nextWritePointer = handle->bufferPointer[0];
+
+    DWORD endWrite, leadPointer;
+    while ( true ) {
+      // Find out where the read and "safe write" pointers are.
+      result = dsBuffer->GetCurrentPosition( &currentWritePointer, &safeWritePointer );
+      if ( FAILED( result ) ) {
+        errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
+        errorText_ = errorStream_.str();
+        error( RtAudioError::SYSTEM_ERROR );
+        return;
+      }
+
+      // We will copy our output buffer into the region between
+      // safeWritePointer and leadPointer.  If leadPointer is not
+      // beyond the next endWrite position, wait until it is.
+      leadPointer = safeWritePointer + handle->dsPointerLeadTime[0];
+      //std::cout << "safeWritePointer = " << safeWritePointer << ", leadPointer = " << leadPointer << ", nextWritePointer = " << nextWritePointer << std::endl;
+      if ( leadPointer > dsBufferSize ) leadPointer -= dsBufferSize;
+      if ( leadPointer < nextWritePointer ) leadPointer += dsBufferSize; // unwrap offset
+      endWrite = nextWritePointer + bufferBytes;
+
+      // Check whether the entire write region is behind the play pointer.
+      if ( leadPointer >= endWrite ) break;
+
+      // If we are here, then we must wait until the leadPointer advances
+      // beyond the end of our next write region. We use the
+      // Sleep() function to suspend operation until that happens.
+      double millis = ( endWrite - leadPointer ) * 1000.0;
+      millis /= ( formatBytes( stream_.deviceFormat[0]) * stream_.nDeviceChannels[0] * stream_.sampleRate);
+      if ( millis < 1.0 ) millis = 1.0;
+      Sleep( (DWORD) millis );
+    }
+
+    if ( dsPointerBetween( nextWritePointer, safeWritePointer, currentWritePointer, dsBufferSize )
+         || dsPointerBetween( endWrite, safeWritePointer, currentWritePointer, dsBufferSize ) ) { 
+      // We've strayed into the forbidden zone ... resync the read pointer.
+      handle->xrun[0] = true;
+      nextWritePointer = safeWritePointer + handle->dsPointerLeadTime[0] - bufferBytes;
+      if ( nextWritePointer >= dsBufferSize ) nextWritePointer -= dsBufferSize;
+      handle->bufferPointer[0] = nextWritePointer;
+      endWrite = nextWritePointer + bufferBytes;
+    }
+
+    // Lock free space in the buffer
+    result = dsBuffer->Lock( nextWritePointer, bufferBytes, &buffer1,
+                             &bufferSize1, &buffer2, &bufferSize2, 0 );
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking buffer during playback!";
+      errorText_ = errorStream_.str();
+      error( RtAudioError::SYSTEM_ERROR );
+      return;
+    }
+
+    // Copy our buffer into the DS buffer
+    CopyMemory( buffer1, buffer, bufferSize1 );
+    if ( buffer2 != NULL ) CopyMemory( buffer2, buffer+bufferSize1, bufferSize2 );
+
+    // Update our buffer offset and unlock sound buffer
+    dsBuffer->Unlock( buffer1, bufferSize1, buffer2, bufferSize2 );
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking buffer during playback!";
+      errorText_ = errorStream_.str();
+      error( RtAudioError::SYSTEM_ERROR );
+      return;
+    }
+    nextWritePointer = ( nextWritePointer + bufferSize1 + bufferSize2 ) % dsBufferSize;
+    handle->bufferPointer[0] = nextWritePointer;
+  }
+
+  // Don't bother draining input
+  if ( handle->drainCounter ) {
+    handle->drainCounter++;
+    goto unlock;
+  }
+
+  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
+
+    // Setup parameters.
+    if ( stream_.doConvertBuffer[1] ) {
+      buffer = stream_.deviceBuffer;
+      bufferBytes = stream_.bufferSize * stream_.nDeviceChannels[1];
+      bufferBytes *= formatBytes( stream_.deviceFormat[1] );
+    }
+    else {
+      buffer = stream_.userBuffer[1];
+      bufferBytes = stream_.bufferSize * stream_.nUserChannels[1];
+      bufferBytes *= formatBytes( stream_.userFormat );
+    }
+
+    LPDIRECTSOUNDCAPTUREBUFFER dsBuffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
+    long nextReadPointer = handle->bufferPointer[1];
+    DWORD dsBufferSize = handle->dsBufferSize[1];
+
+    // Find out where the write and "safe read" pointers are.
+    result = dsBuffer->GetCurrentPosition( &currentReadPointer, &safeReadPointer );
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
+      errorText_ = errorStream_.str();
+      error( RtAudioError::SYSTEM_ERROR );
+      return;
+    }
+
+    if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset
+    DWORD endRead = nextReadPointer + bufferBytes;
+
+    // Handling depends on whether we are INPUT or DUPLEX. 
+    // If we're in INPUT mode then waiting is a good thing. If we're in DUPLEX mode,
+    // then a wait here will drag the write pointers into the forbidden zone.
+    // 
+    // In DUPLEX mode, rather than wait, we will back off the read pointer until 
+    // it's in a safe position. This causes dropouts, but it seems to be the only 
+    // practical way to sync up the read and write pointers reliably, given the 
+    // the very complex relationship between phase and increment of the read and write 
+    // pointers.
+    //
+    // In order to minimize audible dropouts in DUPLEX mode, we will
+    // provide a pre-roll period of 0.5 seconds in which we return
+    // zeros from the read buffer while the pointers sync up.
+
+    if ( stream_.mode == DUPLEX ) {
+      if ( safeReadPointer < endRead ) {
+        if ( duplexPrerollBytes <= 0 ) {
+          // Pre-roll time over. Be more agressive.
+          int adjustment = endRead-safeReadPointer;
+
+          handle->xrun[1] = true;
+          // Two cases:
+          //   - large adjustments: we've probably run out of CPU cycles, so just resync exactly,
+          //     and perform fine adjustments later.
+          //   - small adjustments: back off by twice as much.
+          if ( adjustment >= 2*bufferBytes )
+            nextReadPointer = safeReadPointer-2*bufferBytes;
+          else
+            nextReadPointer = safeReadPointer-bufferBytes-adjustment;
+
+          if ( nextReadPointer < 0 ) nextReadPointer += dsBufferSize;
+
+        }
+        else {
+          // In pre=roll time. Just do it.
+          nextReadPointer = safeReadPointer - bufferBytes;
+          while ( nextReadPointer < 0 ) nextReadPointer += dsBufferSize;
+        }
+        endRead = nextReadPointer + bufferBytes;
+      }
+    }
+    else { // mode == INPUT
+      while ( safeReadPointer < endRead && stream_.callbackInfo.isRunning ) {
+        // See comments for playback.
+        double millis = (endRead - safeReadPointer) * 1000.0;
+        millis /= ( formatBytes(stream_.deviceFormat[1]) * stream_.nDeviceChannels[1] * stream_.sampleRate);
+        if ( millis < 1.0 ) millis = 1.0;
+        Sleep( (DWORD) millis );
+
+        // Wake up and find out where we are now.
+        result = dsBuffer->GetCurrentPosition( &currentReadPointer, &safeReadPointer );
+        if ( FAILED( result ) ) {
+          errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
+          errorText_ = errorStream_.str();
+          error( RtAudioError::SYSTEM_ERROR );
+          return;
+        }
+      
+        if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset
+      }
+    }
+
+    // Lock free space in the buffer
+    result = dsBuffer->Lock( nextReadPointer, bufferBytes, &buffer1,
+                             &bufferSize1, &buffer2, &bufferSize2, 0 );
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking capture buffer!";
+      errorText_ = errorStream_.str();
+      error( RtAudioError::SYSTEM_ERROR );
+      return;
+    }
+
+    if ( duplexPrerollBytes <= 0 ) {
+      // Copy our buffer into the DS buffer
+      CopyMemory( buffer, buffer1, bufferSize1 );
+      if ( buffer2 != NULL ) CopyMemory( buffer+bufferSize1, buffer2, bufferSize2 );
+    }
+    else {
+      memset( buffer, 0, bufferSize1 );
+      if ( buffer2 != NULL ) memset( buffer + bufferSize1, 0, bufferSize2 );
+      duplexPrerollBytes -= bufferSize1 + bufferSize2;
+    }
+
+    // Update our buffer offset and unlock sound buffer
+    nextReadPointer = ( nextReadPointer + bufferSize1 + bufferSize2 ) % dsBufferSize;
+    dsBuffer->Unlock( buffer1, bufferSize1, buffer2, bufferSize2 );
+    if ( FAILED( result ) ) {
+      errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking capture buffer!";
+      errorText_ = errorStream_.str();
+      error( RtAudioError::SYSTEM_ERROR );
+      return;
+    }
+    handle->bufferPointer[1] = nextReadPointer;
+
+    // No byte swapping necessary in DirectSound implementation.
+
+    // If necessary, convert 8-bit data from unsigned to signed.
+    if ( stream_.deviceFormat[1] == RTAUDIO_SINT8 )
+      for ( int j=0; j<bufferBytes; j++ ) buffer[j] = (signed char) ( buffer[j] - 128 );
+
+    // Do buffer conversion if necessary.
+    if ( stream_.doConvertBuffer[1] )
+      convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
+  }
+
+ unlock:
+  MUTEX_UNLOCK( &stream_.mutex );
+  RtApi::tickStreamTime();
+}
+
+// Definitions for utility functions and callbacks
+// specific to the DirectSound implementation.
+
+static unsigned __stdcall callbackHandler( void *ptr )
+{
+  CallbackInfo *info = (CallbackInfo *) ptr;
+  RtApiDs *object = (RtApiDs *) info->object;
+  bool* isRunning = &info->isRunning;
+
+  while ( *isRunning == true ) {
+    object->callbackEvent();
+  }
+
+  _endthreadex( 0 );
+  return 0;
+}
+
+#include "tchar.h"
+
+static std::string convertTChar( LPCTSTR name )
+{
+#if defined( UNICODE ) || defined( _UNICODE )
+  int length = WideCharToMultiByte(CP_UTF8, 0, name, -1, NULL, 0, NULL, NULL);
+  std::string s( length-1, '\0' );
+  WideCharToMultiByte(CP_UTF8, 0, name, -1, &s[0], length, NULL, NULL);
+#else
+  std::string s( name );
+#endif
+
+  return s;
+}
+
+static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
+                                          LPCTSTR description,
+                                          LPCTSTR /*module*/,
+                                          LPVOID lpContext )
+{
+  struct DsProbeData& probeInfo = *(struct DsProbeData*) lpContext;
+  std::vector<struct DsDevice>& dsDevices = *probeInfo.dsDevices;
+
+  HRESULT hr;
+  bool validDevice = false;
+  if ( probeInfo.isInput == true ) {
+    DSCCAPS caps;
+    LPDIRECTSOUNDCAPTURE object;
+
+    hr = DirectSoundCaptureCreate(  lpguid, &object,   NULL );
+    if ( hr != DS_OK ) return TRUE;
+
+    caps.dwSize = sizeof(caps);
+    hr = object->GetCaps( &caps );
+    if ( hr == DS_OK ) {
+      if ( caps.dwChannels > 0 && caps.dwFormats > 0 )
+        validDevice = true;
+    }
+    object->Release();
+  }
+  else {
+    DSCAPS caps;
+    LPDIRECTSOUND object;
+    hr = DirectSoundCreate(  lpguid, &object,   NULL );
+    if ( hr != DS_OK ) return TRUE;
+
+    caps.dwSize = sizeof(caps);
+    hr = object->GetCaps( &caps );
+    if ( hr == DS_OK ) {
+      if ( caps.dwFlags & DSCAPS_PRIMARYMONO || caps.dwFlags & DSCAPS_PRIMARYSTEREO )
+        validDevice = true;
+    }
+    object->Release();
+  }
+
+  // If good device, then save its name and guid.
+  std::string name = convertTChar( description );
+  //if ( name == "Primary Sound Driver" || name == "Primary Sound Capture Driver" )
+  if ( lpguid == NULL )
+    name = "Default Device";
+  if ( validDevice ) {
+    for ( unsigned int i=0; i<dsDevices.size(); i++ ) {
+      if ( dsDevices[i].name == name ) {
+        dsDevices[i].found = true;
+        if ( probeInfo.isInput ) {
+          dsDevices[i].id[1] = lpguid;
+          dsDevices[i].validId[1] = true;
+        }
+        else {
+          dsDevices[i].id[0] = lpguid;
+          dsDevices[i].validId[0] = true;
+        }
+        return TRUE;
+      }
+    }
+
+    DsDevice device;
+    device.name = name;
+    device.found = true;
+    if ( probeInfo.isInput ) {
+      device.id[1] = lpguid;
+      device.validId[1] = true;
+    }
+    else {
+      device.id[0] = lpguid;
+      device.validId[0] = true;
+    }
+    dsDevices.push_back( device );
+  }
+
+  return TRUE;
+}
+
+static const char* getErrorString( int code )
+{
+  switch ( code ) {
+
+  case DSERR_ALLOCATED:
+    return "Already allocated";
+
+  case DSERR_CONTROLUNAVAIL:
+    return "Control unavailable";
+
+  case DSERR_INVALIDPARAM:
+    return "Invalid parameter";
+
+  case DSERR_INVALIDCALL:
+    return "Invalid call";
+
+  case DSERR_GENERIC:
+    return "Generic error";
+
+  case DSERR_PRIOLEVELNEEDED:
+    return "Priority level needed";
+
+  case DSERR_OUTOFMEMORY:
+    return "Out of memory";
+
+  case DSERR_BADFORMAT:
+    return "The sample rate or the channel format is not supported";
+
+  case DSERR_UNSUPPORTED:
+    return "Not supported";
+
+  case DSERR_NODRIVER:
+    return "No driver";
+
+  case DSERR_ALREADYINITIALIZED:
+    return "Already initialized";
+
+  case DSERR_NOAGGREGATION:
+    return "No aggregation";
+
+  case DSERR_BUFFERLOST:
+    return "Buffer lost";
+
+  case DSERR_OTHERAPPHASPRIO:
+    return "Another application already has priority";
+
+  case DSERR_UNINITIALIZED:
+    return "Uninitialized";
+
+  default:
+    return "DirectSound unknown error";
+  }
+}
+//******************** End of __WINDOWS_DS__ *********************//
+#endif
+
+
+#if defined(__LINUX_ALSA__)
+
+#include <alsa/asoundlib.h>
+#include <unistd.h>
+
+  // A structure to hold various information related to the ALSA API
+  // implementation.
+struct AlsaHandle {
+  snd_pcm_t *handles[2];
+  bool synchronized;
+  bool xrun[2];
+  pthread_cond_t runnable_cv;
+  bool runnable;
+
+  AlsaHandle()
+    :synchronized(false), runnable(false) { xrun[0] = false; xrun[1] = false; }
+};
+
+static void *alsaCallbackHandler( void * ptr );
+
+RtApiAlsa :: RtApiAlsa()
+{
+  // Nothing to do here.
+}
+
+RtApiAlsa :: ~RtApiAlsa()
+{
+  if ( stream_.state != STREAM_CLOSED ) closeStream();
+}
+
+unsigned int RtApiAlsa :: getDeviceCount( void )
+{
+  unsigned nDevices = 0;
+  int result, subdevice, card;
+  char name[64];
+  snd_ctl_t *handle;
+
+  // Count cards and devices
+  card = -1;
+  snd_card_next( &card );
+  while ( card >= 0 ) {
+    sprintf( name, "hw:%d", card );
+    result = snd_ctl_open( &handle, name, 0 );
+    if ( result < 0 ) {
+      errorStream_ << "RtApiAlsa::getDeviceCount: control open, card = " << card << ", " << snd_strerror( result ) << ".";
+      errorText_ = errorStream_.str();
+      error( RtAudioError::WARNING );
+      goto nextcard;
+    }
+    subdevice = -1;
+    while( 1 ) {
+      result = snd_ctl_pcm_next_device( handle, &subdevice );
+      if ( result < 0 ) {
+        errorStream_ << "RtApiAlsa::getDeviceCount: control next device, card = " << card << ", " << snd_strerror( result ) << ".";
+        errorText_ = errorStream_.str();
+        error( RtAudioError::WARNING );
+        break;
+      }
+      if ( subdevice < 0 )
+        break;
+      nDevices++;
+    }
+  nextcard:
+    snd_ctl_close( handle );
+    snd_card_next( &card );
+  }
+
+  result = snd_ctl_open( &handle, "default", 0 );
+  if (result == 0) {
+    nDevices++;
+    snd_ctl_close( handle );
+  }
+
+  return nDevices;
+}
+
+RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device )
+{
+  RtAudio::DeviceInfo info;
+  info.probed = false;
+
+  unsigned nDevices = 0;
+  int result, subdevice, card;
+  char name[64];
+  snd_ctl_t *chandle;
+
+  // Count cards and devices
+  card = -1;
+  snd_card_next( &card );
+  while ( card >= 0 ) {
+    sprintf( name, "hw:%d", card );
+    result = snd_ctl_open( &chandle, name, SND_CTL_NONBLOCK );
+    if ( result < 0 ) {
+      errorStream_ << "RtApiAlsa::getDeviceInfo: control open, card = " << card << ", " << snd_strerror( result ) << ".";
+      errorText_ = errorStream_.str();
+      error( RtAudioError::WARNING );
+      goto nextcard;
+    }
+    subdevice = -1;
+    while( 1 ) {
+      result = snd_ctl_pcm_next_device( chandle, &subdevice );
+      if ( result < 0 ) {
+        errorStream_ << "RtApiAlsa::getDeviceInfo: control next device, card = " << card << ", " << snd_strerror( result ) << ".";
+        errorText_ = errorStream_.str();
+        error( RtAudioError::WARNING );
+        break;
+      }
+      if ( subdevice < 0 ) break;
+      if ( nDevices == device ) {
+        sprintf( name, "hw:%d,%d", card, subdevice );
+        goto foundDevice;
+      }
+      nDevices++;
+    }
+  nextcard:
+    snd_ctl_close( chandle );
+    snd_card_next( &card );
+  }
+
+  result = snd_ctl_open( &chandle, "default", SND_CTL_NONBLOCK );
+  if ( result == 0 ) {
+    if ( nDevices == device ) {
+      strcpy( name, "default" );
+      goto foundDevice;
+    }
+    nDevices++;
+  }
+
+  if ( nDevices == 0 ) {
+    errorText_ = "RtApiAlsa::getDeviceInfo: no devices found!";
+    error( RtAudioError::INVALID_USE );
+    return info;
+  }
+
+  if ( device >= nDevices ) {
+    errorText_ = "RtApiAlsa::getDeviceInfo: device ID is invalid!";
+    error( RtAudioError::INVALID_USE );
+    return info;
+  }
+
+ foundDevice:
+
+  // If a stream is already open, we cannot probe the stream devices.
+  // Thus, use the saved results.
+  if ( stream_.state != STREAM_CLOSED &&
+       ( stream_.device[0] == device || stream_.device[1] == device ) ) {
+    snd_ctl_close( chandle );
+    if ( device >= devices_.size() ) {
+      errorText_ = "RtApiAlsa::getDeviceInfo: device ID was not present before stream was opened.";
+      error( RtAudioError::WARNING );
+      return info;
+    }
+    return devices_[ device ];
+  }
+
+  int openMode = SND_PCM_ASYNC;
+  snd_pcm_stream_t stream;
+  snd_pcm_info_t *pcminfo;
+  snd_pcm_info_alloca( &pcminfo );
+  snd_pcm_t *phandle;
+  snd_pcm_hw_params_t *params;
+  snd_pcm_hw_params_alloca( &params );
+
+  // First try for playback unless default device (which has subdev -1)
+  stream = SND_PCM_STREAM_PLAYBACK;
+  snd_pcm_info_set_stream( pcminfo, stream );
+  if ( subdevice != -1 ) {
+    snd_pcm_info_set_device( pcminfo, subdevice );
+    snd_pcm_info_set_subdevice( pcminfo, 0 );
+
+    result = snd_ctl_pcm_info( chandle, pcminfo );
+    if ( result < 0 ) {
+      // Device probably doesn't support playback.
+      goto captureProbe;
+    }
+  }
+
+  result = snd_pcm_open( &phandle, name, stream, openMode | SND_PCM_NONBLOCK );
+  if ( result < 0 ) {
+    errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    goto captureProbe;
+  }
+
+  // The device is open ... fill the parameter structure.
+  result = snd_pcm_hw_params_any( phandle, params );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    goto captureProbe;
+  }
+
+  // Get output channel information.
+  unsigned int value;
+  result = snd_pcm_hw_params_get_channels_max( params, &value );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::getDeviceInfo: error getting device (" << name << ") output channels, " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    goto captureProbe;
+  }
+  info.outputChannels = value;
+  snd_pcm_close( phandle );
+
+ captureProbe:
+  stream = SND_PCM_STREAM_CAPTURE;
+  snd_pcm_info_set_stream( pcminfo, stream );
+
+  // Now try for capture unless default device (with subdev = -1)
+  if ( subdevice != -1 ) {
+    result = snd_ctl_pcm_info( chandle, pcminfo );
+    snd_ctl_close( chandle );
+    if ( result < 0 ) {
+      // Device probably doesn't support capture.
+      if ( info.outputChannels == 0 ) return info;
+      goto probeParameters;
+    }
+  }
+  else
+    snd_ctl_close( chandle );
+
+  result = snd_pcm_open( &phandle, name, stream, openMode | SND_PCM_NONBLOCK);
+  if ( result < 0 ) {
+    errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    if ( info.outputChannels == 0 ) return info;
+    goto probeParameters;
+  }
+
+  // The device is open ... fill the parameter structure.
+  result = snd_pcm_hw_params_any( phandle, params );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    if ( info.outputChannels == 0 ) return info;
+    goto probeParameters;
+  }
+
+  result = snd_pcm_hw_params_get_channels_max( params, &value );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::getDeviceInfo: error getting device (" << name << ") input channels, " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    if ( info.outputChannels == 0 ) return info;
+    goto probeParameters;
+  }
+  info.inputChannels = value;
+  snd_pcm_close( phandle );
+
+  // If device opens for both playback and capture, we determine the channels.
+  if ( info.outputChannels > 0 && info.inputChannels > 0 )
+    info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
+
+  // ALSA doesn't provide default devices so we'll use the first available one.
+  if ( device == 0 && info.outputChannels > 0 )
+    info.isDefaultOutput = true;
+  if ( device == 0 && info.inputChannels > 0 )
+    info.isDefaultInput = true;
+
+ probeParameters:
+  // At this point, we just need to figure out the supported data
+  // formats and sample rates.  We'll proceed by opening the device in
+  // the direction with the maximum number of channels, or playback if
+  // they are equal.  This might limit our sample rate options, but so
+  // be it.
+
+  if ( info.outputChannels >= info.inputChannels )
+    stream = SND_PCM_STREAM_PLAYBACK;
+  else
+    stream = SND_PCM_STREAM_CAPTURE;
+  snd_pcm_info_set_stream( pcminfo, stream );
+
+  result = snd_pcm_open( &phandle, name, stream, openMode | SND_PCM_NONBLOCK);
+  if ( result < 0 ) {
+    errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // The device is open ... fill the parameter structure.
+  result = snd_pcm_hw_params_any( phandle, params );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // Test our discrete set of sample rate values.
+  info.sampleRates.clear();
+  for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) {
+    if ( snd_pcm_hw_params_test_rate( phandle, params, SAMPLE_RATES[i], 0 ) == 0 )
+      info.sampleRates.push_back( SAMPLE_RATES[i] );
+  }
+  if ( info.sampleRates.size() == 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::getDeviceInfo: no supported sample rates found for device (" << name << ").";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // Probe the supported data formats ... we don't care about endian-ness just yet
+  snd_pcm_format_t format;
+  info.nativeFormats = 0;
+  format = SND_PCM_FORMAT_S8;
+  if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 )
+    info.nativeFormats |= RTAUDIO_SINT8;
+  format = SND_PCM_FORMAT_S16;
+  if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 )
+    info.nativeFormats |= RTAUDIO_SINT16;
+  format = SND_PCM_FORMAT_S24;
+  if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 )
+    info.nativeFormats |= RTAUDIO_SINT24;
+  format = SND_PCM_FORMAT_S32;
+  if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 )
+    info.nativeFormats |= RTAUDIO_SINT32;
+  format = SND_PCM_FORMAT_FLOAT;
+  if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 )
+    info.nativeFormats |= RTAUDIO_FLOAT32;
+  format = SND_PCM_FORMAT_FLOAT64;
+  if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 )
+    info.nativeFormats |= RTAUDIO_FLOAT64;
+
+  // Check that we have at least one supported format
+  if ( info.nativeFormats == 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::getDeviceInfo: pcm device (" << name << ") data format not supported by RtAudio.";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // Get the device name
+  char *cardname;
+  result = snd_card_get_name( card, &cardname );
+  if ( result >= 0 ) {
+    sprintf( name, "hw:%s,%d", cardname, subdevice );
+    free( cardname );
+  }
+  info.name = name;
+
+  // That's all ... close the device and return
+  snd_pcm_close( phandle );
+  info.probed = true;
+  return info;
+}
+
+void RtApiAlsa :: saveDeviceInfo( void )
+{
+  devices_.clear();
+
+  unsigned int nDevices = getDeviceCount();
+  devices_.resize( nDevices );
+  for ( unsigned int i=0; i<nDevices; i++ )
+    devices_[i] = getDeviceInfo( i );
+}
+
+bool RtApiAlsa :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
+                                   unsigned int firstChannel, unsigned int sampleRate,
+                                   RtAudioFormat format, unsigned int *bufferSize,
+                                   RtAudio::StreamOptions *options )
+
+{
+#if defined(__RTAUDIO_DEBUG__)
+  snd_output_t *out;
+  snd_output_stdio_attach(&out, stderr, 0);
+#endif
+
+  // I'm not using the "plug" interface ... too much inconsistent behavior.
+
+  unsigned nDevices = 0;
+  int result, subdevice, card;
+  char name[64];
+  snd_ctl_t *chandle;
+
+  if ( options && options->flags & RTAUDIO_ALSA_USE_DEFAULT )
+    snprintf(name, sizeof(name), "%s", "default");
+  else {
+    // Count cards and devices
+    card = -1;
+    snd_card_next( &card );
+    while ( card >= 0 ) {
+      sprintf( name, "hw:%d", card );
+      result = snd_ctl_open( &chandle, name, SND_CTL_NONBLOCK );
+      if ( result < 0 ) {
+        errorStream_ << "RtApiAlsa::probeDeviceOpen: control open, card = " << card << ", " << snd_strerror( result ) << ".";
+        errorText_ = errorStream_.str();
+        return FAILURE;
+      }
+      subdevice = -1;
+      while( 1 ) {
+        result = snd_ctl_pcm_next_device( chandle, &subdevice );
+        if ( result < 0 ) break;
+        if ( subdevice < 0 ) break;
+        if ( nDevices == device ) {
+          sprintf( name, "hw:%d,%d", card, subdevice );
+          snd_ctl_close( chandle );
+          goto foundDevice;
+        }
+        nDevices++;
+      }
+      snd_ctl_close( chandle );
+      snd_card_next( &card );
+    }
+
+    result = snd_ctl_open( &chandle, "default", SND_CTL_NONBLOCK );
+    if ( result == 0 ) {
+      if ( nDevices == device ) {
+        strcpy( name, "default" );
+        goto foundDevice;
+      }
+      nDevices++;
+    }
+
+    if ( nDevices == 0 ) {
+      // This should not happen because a check is made before this function is called.
+      errorText_ = "RtApiAlsa::probeDeviceOpen: no devices found!";
+      return FAILURE;
+    }
+
+    if ( device >= nDevices ) {
+      // This should not happen because a check is made before this function is called.
+      errorText_ = "RtApiAlsa::probeDeviceOpen: device ID is invalid!";
+      return FAILURE;
+    }
+  }
+
+ foundDevice:
+
+  // The getDeviceInfo() function will not work for a device that is
+  // already open.  Thus, we'll probe the system before opening a
+  // stream and save the results for use by getDeviceInfo().
+  if ( mode == OUTPUT || ( mode == INPUT && stream_.mode != OUTPUT ) ) // only do once
+    this->saveDeviceInfo();
+
+  snd_pcm_stream_t stream;
+  if ( mode == OUTPUT )
+    stream = SND_PCM_STREAM_PLAYBACK;
+  else
+    stream = SND_PCM_STREAM_CAPTURE;
+
+  snd_pcm_t *phandle;
+  int openMode = SND_PCM_ASYNC;
+  result = snd_pcm_open( &phandle, name, stream, openMode );
+  if ( result < 0 ) {
+    if ( mode == OUTPUT )
+      errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device (" << name << ") won't open for output.";
+    else
+      errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device (" << name << ") won't open for input.";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Fill the parameter structure.
+  snd_pcm_hw_params_t *hw_params;
+  snd_pcm_hw_params_alloca( &hw_params );
+  result = snd_pcm_hw_params_any( phandle, hw_params );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") parameters, " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+#if defined(__RTAUDIO_DEBUG__)
+  fprintf( stderr, "\nRtApiAlsa: dump hardware params just after device open:\n\n" );
+  snd_pcm_hw_params_dump( hw_params, out );
+#endif
+
+  // Set access ... check user preference.
+  if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) {
+    stream_.userInterleaved = false;
+    result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED );
+    if ( result < 0 ) {
+      result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED );
+      stream_.deviceInterleaved[mode] =  true;
+    }
+    else
+      stream_.deviceInterleaved[mode] = false;
+  }
+  else {
+    stream_.userInterleaved = true;
+    result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED );
+    if ( result < 0 ) {
+      result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED );
+      stream_.deviceInterleaved[mode] =  false;
+    }
+    else
+      stream_.deviceInterleaved[mode] =  true;
+  }
+
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") access, " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Determine how to set the device format.
+  stream_.userFormat = format;
+  snd_pcm_format_t deviceFormat = SND_PCM_FORMAT_UNKNOWN;
+
+  if ( format == RTAUDIO_SINT8 )
+    deviceFormat = SND_PCM_FORMAT_S8;
+  else if ( format == RTAUDIO_SINT16 )
+    deviceFormat = SND_PCM_FORMAT_S16;
+  else if ( format == RTAUDIO_SINT24 )
+    deviceFormat = SND_PCM_FORMAT_S24;
+  else if ( format == RTAUDIO_SINT32 )
+    deviceFormat = SND_PCM_FORMAT_S32;
+  else if ( format == RTAUDIO_FLOAT32 )
+    deviceFormat = SND_PCM_FORMAT_FLOAT;
+  else if ( format == RTAUDIO_FLOAT64 )
+    deviceFormat = SND_PCM_FORMAT_FLOAT64;
+
+  if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) {
+    stream_.deviceFormat[mode] = format;
+    goto setFormat;
+  }
+
+  // The user requested format is not natively supported by the device.
+  deviceFormat = SND_PCM_FORMAT_FLOAT64;
+  if ( snd_pcm_hw_params_test_format( phandle, hw_params, deviceFormat ) == 0 ) {
+    stream_.deviceFormat[mode] = RTAUDIO_FLOAT64;
+    goto setFormat;
+  }
+
+  deviceFormat = SND_PCM_FORMAT_FLOAT;
+  if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
+    stream_.deviceFormat[mode] = RTAUDIO_FLOAT32;
+    goto setFormat;
+  }
+
+  deviceFormat = SND_PCM_FORMAT_S32;
+  if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
+    stream_.deviceFormat[mode] = RTAUDIO_SINT32;
+    goto setFormat;
+  }
+
+  deviceFormat = SND_PCM_FORMAT_S24;
+  if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
+    stream_.deviceFormat[mode] = RTAUDIO_SINT24;
+    goto setFormat;
+  }
+
+  deviceFormat = SND_PCM_FORMAT_S16;
+  if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
+    stream_.deviceFormat[mode] = RTAUDIO_SINT16;
+    goto setFormat;
+  }
+
+  deviceFormat = SND_PCM_FORMAT_S8;
+  if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
+    stream_.deviceFormat[mode] = RTAUDIO_SINT8;
+    goto setFormat;
+  }
+
+  // If we get here, no supported format was found.
+  snd_pcm_close( phandle );
+  errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device " << device << " data format not supported by RtAudio.";
+  errorText_ = errorStream_.str();
+  return FAILURE;
+
+ setFormat:
+  result = snd_pcm_hw_params_set_format( phandle, hw_params, deviceFormat );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") data format, " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Determine whether byte-swaping is necessary.
+  stream_.doByteSwap[mode] = false;
+  if ( deviceFormat != SND_PCM_FORMAT_S8 ) {
+    result = snd_pcm_format_cpu_endian( deviceFormat );
+    if ( result == 0 )
+      stream_.doByteSwap[mode] = true;
+    else if (result < 0) {
+      snd_pcm_close( phandle );
+      errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") endian-ness, " << snd_strerror( result ) << ".";
+      errorText_ = errorStream_.str();
+      return FAILURE;
+    }
+  }
+
+  // Set the sample rate.
+  result = snd_pcm_hw_params_set_rate_near( phandle, hw_params, (unsigned int*) &sampleRate, 0 );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting sample rate on device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Determine the number of channels for this device.  We support a possible
+  // minimum device channel number > than the value requested by the user.
+  stream_.nUserChannels[mode] = channels;
+  unsigned int value;
+  result = snd_pcm_hw_params_get_channels_max( hw_params, &value );
+  unsigned int deviceChannels = value;
+  if ( result < 0 || deviceChannels < channels + firstChannel ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::probeDeviceOpen: requested channel parameters not supported by device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  result = snd_pcm_hw_params_get_channels_min( hw_params, &value );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting minimum channels for device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+  deviceChannels = value;
+  if ( deviceChannels < channels + firstChannel ) deviceChannels = channels + firstChannel;
+  stream_.nDeviceChannels[mode] = deviceChannels;
+
+  // Set the device channels.
+  result = snd_pcm_hw_params_set_channels( phandle, hw_params, deviceChannels );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting channels for device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Set the buffer (or period) size.
+  int dir = 0;
+  snd_pcm_uframes_t periodSize = *bufferSize;
+  result = snd_pcm_hw_params_set_period_size_near( phandle, hw_params, &periodSize, &dir );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting period size for device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+  *bufferSize = periodSize;
+
+  // Set the buffer number, which in ALSA is referred to as the "period".
+  unsigned int periods = 0;
+  if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) periods = 2;
+  if ( options && options->numberOfBuffers > 0 ) periods = options->numberOfBuffers;
+  if ( periods < 2 ) periods = 4; // a fairly safe default value
+  result = snd_pcm_hw_params_set_periods_near( phandle, hw_params, &periods, &dir );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting periods for device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // If attempting to setup a duplex stream, the bufferSize parameter
+  // MUST be the same in both directions!
+  if ( stream_.mode == OUTPUT && mode == INPUT && *bufferSize != stream_.bufferSize ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << name << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  stream_.bufferSize = *bufferSize;
+
+  // Install the hardware configuration
+  result = snd_pcm_hw_params( phandle, hw_params );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing hardware configuration on device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+#if defined(__RTAUDIO_DEBUG__)
+  fprintf(stderr, "\nRtApiAlsa: dump hardware params after installation:\n\n");
+  snd_pcm_hw_params_dump( hw_params, out );
+#endif
+
+  // Set the software configuration to fill buffers with zeros and prevent device stopping on xruns.
+  snd_pcm_sw_params_t *sw_params = NULL;
+  snd_pcm_sw_params_alloca( &sw_params );
+  snd_pcm_sw_params_current( phandle, sw_params );
+  snd_pcm_sw_params_set_start_threshold( phandle, sw_params, *bufferSize );
+  snd_pcm_sw_params_set_stop_threshold( phandle, sw_params, ULONG_MAX );
+  snd_pcm_sw_params_set_silence_threshold( phandle, sw_params, 0 );
+
+  // The following two settings were suggested by Theo Veenker
+  //snd_pcm_sw_params_set_avail_min( phandle, sw_params, *bufferSize );
+  //snd_pcm_sw_params_set_xfer_align( phandle, sw_params, 1 );
+
+  // here are two options for a fix
+  //snd_pcm_sw_params_set_silence_size( phandle, sw_params, ULONG_MAX );
+  snd_pcm_uframes_t val;
+  snd_pcm_sw_params_get_boundary( sw_params, &val );
+  snd_pcm_sw_params_set_silence_size( phandle, sw_params, val );
+
+  result = snd_pcm_sw_params( phandle, sw_params );
+  if ( result < 0 ) {
+    snd_pcm_close( phandle );
+    errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing software configuration on device (" << name << "), " << snd_strerror( result ) << ".";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+#if defined(__RTAUDIO_DEBUG__)
+  fprintf(stderr, "\nRtApiAlsa: dump software params after installation:\n\n");
+  snd_pcm_sw_params_dump( sw_params, out );
+#endif
+
+  // Set flags for buffer conversion
+  stream_.doConvertBuffer[mode] = false;
+  if ( stream_.userFormat != stream_.deviceFormat[mode] )
+    stream_.doConvertBuffer[mode] = true;
+  if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] )
+    stream_.doConvertBuffer[mode] = true;
+  if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
+       stream_.nUserChannels[mode] > 1 )
+    stream_.doConvertBuffer[mode] = true;
+
+  // Allocate the ApiHandle if necessary and then save.
+  AlsaHandle *apiInfo = 0;
+  if ( stream_.apiHandle == 0 ) {
+    try {
+      apiInfo = (AlsaHandle *) new AlsaHandle;
+    }
+    catch ( std::bad_alloc& ) {
+      errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating AlsaHandle memory.";
+      goto error;
+    }
+
+    if ( pthread_cond_init( &apiInfo->runnable_cv, NULL ) ) {
+      errorText_ = "RtApiAlsa::probeDeviceOpen: error initializing pthread condition variable.";
+      goto error;
+    }
+
+    stream_.apiHandle = (void *) apiInfo;
+    apiInfo->handles[0] = 0;
+    apiInfo->handles[1] = 0;
+  }
+  else {
+    apiInfo = (AlsaHandle *) stream_.apiHandle;
+  }
+  apiInfo->handles[mode] = phandle;
+  phandle = 0;
+
+  // Allocate necessary internal buffers.
+  unsigned long bufferBytes;
+  bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
+  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
+  if ( stream_.userBuffer[mode] == NULL ) {
+    errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating user buffer memory.";
+    goto error;
+  }
+
+  if ( stream_.doConvertBuffer[mode] ) {
+
+    bool makeBuffer = true;
+    bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
+    if ( mode == INPUT ) {
+      if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
+        unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
+        if ( bufferBytes <= bytesOut ) makeBuffer = false;
+      }
+    }
+
+    if ( makeBuffer ) {
+      bufferBytes *= *bufferSize;
+      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
+      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
+      if ( stream_.deviceBuffer == NULL ) {
+        errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating device buffer memory.";
+        goto error;
+      }
+    }
+  }
+
+  stream_.sampleRate = sampleRate;
+  stream_.nBuffers = periods;
+  stream_.device[mode] = device;
+  stream_.state = STREAM_STOPPED;
+
+  // Setup the buffer conversion information structure.
+  if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel );
+
+  // Setup thread if necessary.
+  if ( stream_.mode == OUTPUT && mode == INPUT ) {
+    // We had already set up an output stream.
+    stream_.mode = DUPLEX;
+    // Link the streams if possible.
+    apiInfo->synchronized = false;
+    if ( snd_pcm_link( apiInfo->handles[0], apiInfo->handles[1] ) == 0 )
+      apiInfo->synchronized = true;
+    else {
+      errorText_ = "RtApiAlsa::probeDeviceOpen: unable to synchronize input and output devices.";
+      error( RtAudioError::WARNING );
+    }
+  }
+  else {
+    stream_.mode = mode;
+
+    // Setup callback thread.
+    stream_.callbackInfo.object = (void *) this;
+
+    // Set the thread attributes for joinable and realtime scheduling
+    // priority (optional).  The higher priority will only take affect
+    // if the program is run as root or suid. Note, under Linux
+    // processes with CAP_SYS_NICE privilege, a user can change
+    // scheduling policy and priority (thus need not be root). See
+    // POSIX "capabilities".
+    pthread_attr_t attr;
+    pthread_attr_init( &attr );
+    pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
+
+#ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread)
+    if ( options && options->flags & RTAUDIO_SCHEDULE_REALTIME ) {
+      // We previously attempted to increase the audio callback priority
+      // to SCHED_RR here via the attributes.  However, while no errors
+      // were reported in doing so, it did not work.  So, now this is
+      // done in the alsaCallbackHandler function.
+      stream_.callbackInfo.doRealtime = true;
+      int priority = options->priority;
+      int min = sched_get_priority_min( SCHED_RR );
+      int max = sched_get_priority_max( SCHED_RR );
+      if ( priority < min ) priority = min;
+      else if ( priority > max ) priority = max;
+      stream_.callbackInfo.priority = priority;
+    }
+#endif
+
+    stream_.callbackInfo.isRunning = true;
+    result = pthread_create( &stream_.callbackInfo.thread, &attr, alsaCallbackHandler, &stream_.callbackInfo );
+    pthread_attr_destroy( &attr );
+    if ( result ) {
+      stream_.callbackInfo.isRunning = false;
+      errorText_ = "RtApiAlsa::error creating callback thread!";
+      goto error;
+    }
+  }
+
+  return SUCCESS;
+
+ error:
+  if ( apiInfo ) {
+    pthread_cond_destroy( &apiInfo->runnable_cv );
+    if ( apiInfo->handles[0] ) snd_pcm_close( apiInfo->handles[0] );
+    if ( apiInfo->handles[1] ) snd_pcm_close( apiInfo->handles[1] );
+    delete apiInfo;
+    stream_.apiHandle = 0;
+  }
+
+  if ( phandle) snd_pcm_close( phandle );
+
+  for ( int i=0; i<2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  stream_.state = STREAM_CLOSED;
+  return FAILURE;
+}
+
+void RtApiAlsa :: closeStream()
+{
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiAlsa::closeStream(): no open stream to close!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
+  stream_.callbackInfo.isRunning = false;
+  MUTEX_LOCK( &stream_.mutex );
+  if ( stream_.state == STREAM_STOPPED ) {
+    apiInfo->runnable = true;
+    pthread_cond_signal( &apiInfo->runnable_cv );
+  }
+  MUTEX_UNLOCK( &stream_.mutex );
+  pthread_join( stream_.callbackInfo.thread, NULL );
+
+  if ( stream_.state == STREAM_RUNNING ) {
+    stream_.state = STREAM_STOPPED;
+    if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX )
+      snd_pcm_drop( apiInfo->handles[0] );
+    if ( stream_.mode == INPUT || stream_.mode == DUPLEX )
+      snd_pcm_drop( apiInfo->handles[1] );
+  }
+
+  if ( apiInfo ) {
+    pthread_cond_destroy( &apiInfo->runnable_cv );
+    if ( apiInfo->handles[0] ) snd_pcm_close( apiInfo->handles[0] );
+    if ( apiInfo->handles[1] ) snd_pcm_close( apiInfo->handles[1] );
+    delete apiInfo;
+    stream_.apiHandle = 0;
+  }
+
+  for ( int i=0; i<2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  stream_.mode = UNINITIALIZED;
+  stream_.state = STREAM_CLOSED;
+}
+
+void RtApiAlsa :: startStream()
+{
+  // This method calls snd_pcm_prepare if the device isn't already in that state.
+
+  verifyStream();
+  if ( stream_.state == STREAM_RUNNING ) {
+    errorText_ = "RtApiAlsa::startStream(): the stream is already running!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  MUTEX_LOCK( &stream_.mutex );
+
+  int result = 0;
+  snd_pcm_state_t state;
+  AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
+  snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles;
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+    state = snd_pcm_state( handle[0] );
+    if ( state != SND_PCM_STATE_PREPARED ) {
+      result = snd_pcm_prepare( handle[0] );
+      if ( result < 0 ) {
+        errorStream_ << "RtApiAlsa::startStream: error preparing output pcm device, " << snd_strerror( result ) << ".";
+        errorText_ = errorStream_.str();
+        goto unlock;
+      }
+    }
+  }
+
+  if ( ( stream_.mode == INPUT || stream_.mode == DUPLEX ) && !apiInfo->synchronized ) {
+    result = snd_pcm_drop(handle[1]); // fix to remove stale data received since device has been open
+    state = snd_pcm_state( handle[1] );
+    if ( state != SND_PCM_STATE_PREPARED ) {
+      result = snd_pcm_prepare( handle[1] );
+      if ( result < 0 ) {
+        errorStream_ << "RtApiAlsa::startStream: error preparing input pcm device, " << snd_strerror( result ) << ".";
+        errorText_ = errorStream_.str();
+        goto unlock;
+      }
+    }
+  }
+
+  stream_.state = STREAM_RUNNING;
+
+ unlock:
+  apiInfo->runnable = true;
+  pthread_cond_signal( &apiInfo->runnable_cv );
+  MUTEX_UNLOCK( &stream_.mutex );
+
+  if ( result >= 0 ) return;
+  error( RtAudioError::SYSTEM_ERROR );
+}
+
+void RtApiAlsa :: stopStream()
+{
+  verifyStream();
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiAlsa::stopStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  stream_.state = STREAM_STOPPED;
+  MUTEX_LOCK( &stream_.mutex );
+
+  int result = 0;
+  AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
+  snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles;
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+    if ( apiInfo->synchronized ) 
+      result = snd_pcm_drop( handle[0] );
+    else
+      result = snd_pcm_drain( handle[0] );
+    if ( result < 0 ) {
+      errorStream_ << "RtApiAlsa::stopStream: error draining output pcm device, " << snd_strerror( result ) << ".";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+  }
+
+  if ( ( stream_.mode == INPUT || stream_.mode == DUPLEX ) && !apiInfo->synchronized ) {
+    result = snd_pcm_drop( handle[1] );
+    if ( result < 0 ) {
+      errorStream_ << "RtApiAlsa::stopStream: error stopping input pcm device, " << snd_strerror( result ) << ".";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+  }
+
+ unlock:
+  apiInfo->runnable = false; // fixes high CPU usage when stopped
+  MUTEX_UNLOCK( &stream_.mutex );
+
+  if ( result >= 0 ) return;
+  error( RtAudioError::SYSTEM_ERROR );
+}
+
+void RtApiAlsa :: abortStream()
+{
+  verifyStream();
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiAlsa::abortStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  stream_.state = STREAM_STOPPED;
+  MUTEX_LOCK( &stream_.mutex );
+
+  int result = 0;
+  AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
+  snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles;
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+    result = snd_pcm_drop( handle[0] );
+    if ( result < 0 ) {
+      errorStream_ << "RtApiAlsa::abortStream: error aborting output pcm device, " << snd_strerror( result ) << ".";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+  }
+
+  if ( ( stream_.mode == INPUT || stream_.mode == DUPLEX ) && !apiInfo->synchronized ) {
+    result = snd_pcm_drop( handle[1] );
+    if ( result < 0 ) {
+      errorStream_ << "RtApiAlsa::abortStream: error aborting input pcm device, " << snd_strerror( result ) << ".";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+  }
+
+ unlock:
+  apiInfo->runnable = false; // fixes high CPU usage when stopped
+  MUTEX_UNLOCK( &stream_.mutex );
+
+  if ( result >= 0 ) return;
+  error( RtAudioError::SYSTEM_ERROR );
+}
+
+void RtApiAlsa :: callbackEvent()
+{
+  AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
+  if ( stream_.state == STREAM_STOPPED ) {
+    MUTEX_LOCK( &stream_.mutex );
+    while ( !apiInfo->runnable )
+      pthread_cond_wait( &apiInfo->runnable_cv, &stream_.mutex );
+
+    if ( stream_.state != STREAM_RUNNING ) {
+      MUTEX_UNLOCK( &stream_.mutex );
+      return;
+    }
+    MUTEX_UNLOCK( &stream_.mutex );
+  }
+
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiAlsa::callbackEvent(): the stream is closed ... this shouldn't happen!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  int doStopStream = 0;
+  RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback;
+  double streamTime = getStreamTime();
+  RtAudioStreamStatus status = 0;
+  if ( stream_.mode != INPUT && apiInfo->xrun[0] == true ) {
+    status |= RTAUDIO_OUTPUT_UNDERFLOW;
+    apiInfo->xrun[0] = false;
+  }
+  if ( stream_.mode != OUTPUT && apiInfo->xrun[1] == true ) {
+    status |= RTAUDIO_INPUT_OVERFLOW;
+    apiInfo->xrun[1] = false;
+  }
+  doStopStream = callback( stream_.userBuffer[0], stream_.userBuffer[1],
+                           stream_.bufferSize, streamTime, status, stream_.callbackInfo.userData );
+
+  if ( doStopStream == 2 ) {
+    abortStream();
+    return;
+  }
+
+  MUTEX_LOCK( &stream_.mutex );
+
+  // The state might change while waiting on a mutex.
+  if ( stream_.state == STREAM_STOPPED ) goto unlock;
+
+  int result;
+  char *buffer;
+  int channels;
+  snd_pcm_t **handle;
+  snd_pcm_sframes_t frames;
+  RtAudioFormat format;
+  handle = (snd_pcm_t **) apiInfo->handles;
+
+  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
+
+    // Setup parameters.
+    if ( stream_.doConvertBuffer[1] ) {
+      buffer = stream_.deviceBuffer;
+      channels = stream_.nDeviceChannels[1];
+      format = stream_.deviceFormat[1];
+    }
+    else {
+      buffer = stream_.userBuffer[1];
+      channels = stream_.nUserChannels[1];
+      format = stream_.userFormat;
+    }
+
+    // Read samples from device in interleaved/non-interleaved format.
+    if ( stream_.deviceInterleaved[1] )
+      result = snd_pcm_readi( handle[1], buffer, stream_.bufferSize );
+    else {
+      void *bufs[channels];
+      size_t offset = stream_.bufferSize * formatBytes( format );
+      for ( int i=0; i<channels; i++ )
+        bufs[i] = (void *) (buffer + (i * offset));
+      result = snd_pcm_readn( handle[1], bufs, stream_.bufferSize );
+    }
+
+    if ( result < (int) stream_.bufferSize ) {
+      // Either an error or overrun occured.
+      if ( result == -EPIPE ) {
+        snd_pcm_state_t state = snd_pcm_state( handle[1] );
+        if ( state == SND_PCM_STATE_XRUN ) {
+          apiInfo->xrun[1] = true;
+          result = snd_pcm_prepare( handle[1] );
+          if ( result < 0 ) {
+            errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after overrun, " << snd_strerror( result ) << ".";
+            errorText_ = errorStream_.str();
+          }
+        }
+        else {
+          errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << ".";
+          errorText_ = errorStream_.str();
+        }
+      }
+      else {
+        errorStream_ << "RtApiAlsa::callbackEvent: audio read error, " << snd_strerror( result ) << ".";
+        errorText_ = errorStream_.str();
+      }
+      error( RtAudioError::WARNING );
+      goto tryOutput;
+    }
+
+    // Do byte swapping if necessary.
+    if ( stream_.doByteSwap[1] )
+      byteSwapBuffer( buffer, stream_.bufferSize * channels, format );
+
+    // Do buffer conversion if necessary.
+    if ( stream_.doConvertBuffer[1] )
+      convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
+
+    // Check stream latency
+    result = snd_pcm_delay( handle[1], &frames );
+    if ( result == 0 && frames > 0 ) stream_.latency[1] = frames;
+  }
+
+ tryOutput:
+
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+
+    // Setup parameters and do buffer conversion if necessary.
+    if ( stream_.doConvertBuffer[0] ) {
+      buffer = stream_.deviceBuffer;
+      convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] );
+      channels = stream_.nDeviceChannels[0];
+      format = stream_.deviceFormat[0];
+    }
+    else {
+      buffer = stream_.userBuffer[0];
+      channels = stream_.nUserChannels[0];
+      format = stream_.userFormat;
+    }
+
+    // Do byte swapping if necessary.
+    if ( stream_.doByteSwap[0] )
+      byteSwapBuffer(buffer, stream_.bufferSize * channels, format);
+
+    // Write samples to device in interleaved/non-interleaved format.
+    if ( stream_.deviceInterleaved[0] )
+      result = snd_pcm_writei( handle[0], buffer, stream_.bufferSize );
+    else {
+      void *bufs[channels];
+      size_t offset = stream_.bufferSize * formatBytes( format );
+      for ( int i=0; i<channels; i++ )
+        bufs[i] = (void *) (buffer + (i * offset));
+      result = snd_pcm_writen( handle[0], bufs, stream_.bufferSize );
+    }
+
+    if ( result < (int) stream_.bufferSize ) {
+      // Either an error or underrun occured.
+      if ( result == -EPIPE ) {
+        snd_pcm_state_t state = snd_pcm_state( handle[0] );
+        if ( state == SND_PCM_STATE_XRUN ) {
+          apiInfo->xrun[0] = true;
+          result = snd_pcm_prepare( handle[0] );
+          if ( result < 0 ) {
+            errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after underrun, " << snd_strerror( result ) << ".";
+            errorText_ = errorStream_.str();
+          }
+        }
+        else {
+          errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << ".";
+          errorText_ = errorStream_.str();
+        }
+      }
+      else {
+        errorStream_ << "RtApiAlsa::callbackEvent: audio write error, " << snd_strerror( result ) << ".";
+        errorText_ = errorStream_.str();
+      }
+      error( RtAudioError::WARNING );
+      goto unlock;
+    }
+
+    // Check stream latency
+    result = snd_pcm_delay( handle[0], &frames );
+    if ( result == 0 && frames > 0 ) stream_.latency[0] = frames;
+  }
+
+ unlock:
+  MUTEX_UNLOCK( &stream_.mutex );
+
+  RtApi::tickStreamTime();
+  if ( doStopStream == 1 ) this->stopStream();
+}
+
+static void *alsaCallbackHandler( void *ptr )
+{
+  CallbackInfo *info = (CallbackInfo *) ptr;
+  RtApiAlsa *object = (RtApiAlsa *) info->object;
+  bool *isRunning = &info->isRunning;
+
+#ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread)
+  if ( &info->doRealtime ) {
+    pthread_t tID = pthread_self();	 // ID of this thread
+    sched_param prio = { info->priority }; // scheduling priority of thread
+    pthread_setschedparam( tID, SCHED_RR, &prio );
+  }
+#endif
+
+  while ( *isRunning == true ) {
+    pthread_testcancel();
+    object->callbackEvent();
+  }
+
+  pthread_exit( NULL );
+}
+
+//******************** End of __LINUX_ALSA__ *********************//
+#endif
+
+#if defined(__LINUX_PULSE__)
+
+// Code written by Peter Meerwald, pmeerw@pmeerw.net
+// and Tristan Matthews.
+
+#include <pulse/error.h>
+#include <pulse/simple.h>
+#include <cstdio>
+
+static const unsigned int SUPPORTED_SAMPLERATES[] = { 8000, 16000, 22050, 32000,
+                                                      44100, 48000, 96000, 0};
+
+struct rtaudio_pa_format_mapping_t {
+  RtAudioFormat rtaudio_format;
+  pa_sample_format_t pa_format;
+};
+
+static const rtaudio_pa_format_mapping_t supported_sampleformats[] = {
+  {RTAUDIO_SINT16, PA_SAMPLE_S16LE},
+  {RTAUDIO_SINT32, PA_SAMPLE_S32LE},
+  {RTAUDIO_FLOAT32, PA_SAMPLE_FLOAT32LE},
+  {0, PA_SAMPLE_INVALID}};
+
+struct PulseAudioHandle {
+  pa_simple *s_play;
+  pa_simple *s_rec;
+  pthread_t thread;
+  pthread_cond_t runnable_cv;
+  bool runnable;
+  PulseAudioHandle() : s_play(0), s_rec(0), runnable(false) { }
+};
+
+RtApiPulse::~RtApiPulse()
+{
+  if ( stream_.state != STREAM_CLOSED )
+    closeStream();
+}
+
+unsigned int RtApiPulse::getDeviceCount( void )
+{
+  return 1;
+}
+
+RtAudio::DeviceInfo RtApiPulse::getDeviceInfo( unsigned int /*device*/ )
+{
+  RtAudio::DeviceInfo info;
+  info.probed = true;
+  info.name = "PulseAudio";
+  info.outputChannels = 2;
+  info.inputChannels = 2;
+  info.duplexChannels = 2;
+  info.isDefaultOutput = true;
+  info.isDefaultInput = true;
+
+  for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr )
+    info.sampleRates.push_back( *sr );
+
+  info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32 | RTAUDIO_FLOAT32;
+
+  return info;
+}
+
+static void *pulseaudio_callback( void * user )
+{
+  CallbackInfo *cbi = static_cast<CallbackInfo *>( user );
+  RtApiPulse *context = static_cast<RtApiPulse *>( cbi->object );
+  volatile bool *isRunning = &cbi->isRunning;
+
+  while ( *isRunning ) {
+    pthread_testcancel();
+    context->callbackEvent();
+  }
+
+  pthread_exit( NULL );
+}
+
+void RtApiPulse::closeStream( void )
+{
+  PulseAudioHandle *pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
+
+  stream_.callbackInfo.isRunning = false;
+  if ( pah ) {
+    MUTEX_LOCK( &stream_.mutex );
+    if ( stream_.state == STREAM_STOPPED ) {
+      pah->runnable = true;
+      pthread_cond_signal( &pah->runnable_cv );
+    }
+    MUTEX_UNLOCK( &stream_.mutex );
+
+    pthread_join( pah->thread, 0 );
+    if ( pah->s_play ) {
+      pa_simple_flush( pah->s_play, NULL );
+      pa_simple_free( pah->s_play );
+    }
+    if ( pah->s_rec )
+      pa_simple_free( pah->s_rec );
+
+    pthread_cond_destroy( &pah->runnable_cv );
+    delete pah;
+    stream_.apiHandle = 0;
+  }
+
+  if ( stream_.userBuffer[0] ) {
+    free( stream_.userBuffer[0] );
+    stream_.userBuffer[0] = 0;
+  }
+  if ( stream_.userBuffer[1] ) {
+    free( stream_.userBuffer[1] );
+    stream_.userBuffer[1] = 0;
+  }
+
+  stream_.state = STREAM_CLOSED;
+  stream_.mode = UNINITIALIZED;
+}
+
+void RtApiPulse::callbackEvent( void )
+{
+  PulseAudioHandle *pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
+
+  if ( stream_.state == STREAM_STOPPED ) {
+    MUTEX_LOCK( &stream_.mutex );
+    while ( !pah->runnable )
+      pthread_cond_wait( &pah->runnable_cv, &stream_.mutex );
+
+    if ( stream_.state != STREAM_RUNNING ) {
+      MUTEX_UNLOCK( &stream_.mutex );
+      return;
+    }
+    MUTEX_UNLOCK( &stream_.mutex );
+  }
+
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiPulse::callbackEvent(): the stream is closed ... "
+      "this shouldn't happen!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback;
+  double streamTime = getStreamTime();
+  RtAudioStreamStatus status = 0;
+  int doStopStream = callback( stream_.userBuffer[OUTPUT], stream_.userBuffer[INPUT],
+                               stream_.bufferSize, streamTime, status,
+                               stream_.callbackInfo.userData );
+
+  if ( doStopStream == 2 ) {
+    abortStream();
+    return;
+  }
+
+  MUTEX_LOCK( &stream_.mutex );
+  void *pulse_in = stream_.doConvertBuffer[INPUT] ? stream_.deviceBuffer : stream_.userBuffer[INPUT];
+  void *pulse_out = stream_.doConvertBuffer[OUTPUT] ? stream_.deviceBuffer : stream_.userBuffer[OUTPUT];
+
+  if ( stream_.state != STREAM_RUNNING )
+    goto unlock;
+
+  int pa_error;
+  size_t bytes;
+  if (stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+    if ( stream_.doConvertBuffer[OUTPUT] ) {
+        convertBuffer( stream_.deviceBuffer,
+                       stream_.userBuffer[OUTPUT],
+                       stream_.convertInfo[OUTPUT] );
+        bytes = stream_.nDeviceChannels[OUTPUT] * stream_.bufferSize *
+                formatBytes( stream_.deviceFormat[OUTPUT] );
+    } else
+        bytes = stream_.nUserChannels[OUTPUT] * stream_.bufferSize *
+                formatBytes( stream_.userFormat );
+
+    if ( pa_simple_write( pah->s_play, pulse_out, bytes, &pa_error ) < 0 ) {
+      errorStream_ << "RtApiPulse::callbackEvent: audio write error, " <<
+        pa_strerror( pa_error ) << ".";
+      errorText_ = errorStream_.str();
+      error( RtAudioError::WARNING );
+    }
+  }
+
+  if ( stream_.mode == INPUT || stream_.mode == DUPLEX) {
+    if ( stream_.doConvertBuffer[INPUT] )
+      bytes = stream_.nDeviceChannels[INPUT] * stream_.bufferSize *
+        formatBytes( stream_.deviceFormat[INPUT] );
+    else
+      bytes = stream_.nUserChannels[INPUT] * stream_.bufferSize *
+        formatBytes( stream_.userFormat );
+            
+    if ( pa_simple_read( pah->s_rec, pulse_in, bytes, &pa_error ) < 0 ) {
+      errorStream_ << "RtApiPulse::callbackEvent: audio read error, " <<
+        pa_strerror( pa_error ) << ".";
+      errorText_ = errorStream_.str();
+      error( RtAudioError::WARNING );
+    }
+    if ( stream_.doConvertBuffer[INPUT] ) {
+      convertBuffer( stream_.userBuffer[INPUT],
+                     stream_.deviceBuffer,
+                     stream_.convertInfo[INPUT] );
+    }
+  }
+
+ unlock:
+  MUTEX_UNLOCK( &stream_.mutex );
+  RtApi::tickStreamTime();
+
+  if ( doStopStream == 1 )
+    stopStream();
+}
+
+void RtApiPulse::startStream( void )
+{
+  PulseAudioHandle *pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
+
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiPulse::startStream(): the stream is not open!";
+    error( RtAudioError::INVALID_USE );
+    return;
+  }
+  if ( stream_.state == STREAM_RUNNING ) {
+    errorText_ = "RtApiPulse::startStream(): the stream is already running!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  MUTEX_LOCK( &stream_.mutex );
+
+  stream_.state = STREAM_RUNNING;
+
+  pah->runnable = true;
+  pthread_cond_signal( &pah->runnable_cv );
+  MUTEX_UNLOCK( &stream_.mutex );
+}
+
+void RtApiPulse::stopStream( void )
+{
+  PulseAudioHandle *pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
+
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiPulse::stopStream(): the stream is not open!";
+    error( RtAudioError::INVALID_USE );
+    return;
+  }
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiPulse::stopStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  stream_.state = STREAM_STOPPED;
+  MUTEX_LOCK( &stream_.mutex );
+
+  if ( pah && pah->s_play ) {
+    int pa_error;
+    if ( pa_simple_drain( pah->s_play, &pa_error ) < 0 ) {
+      errorStream_ << "RtApiPulse::stopStream: error draining output device, " <<
+        pa_strerror( pa_error ) << ".";
+      errorText_ = errorStream_.str();
+      MUTEX_UNLOCK( &stream_.mutex );
+      error( RtAudioError::SYSTEM_ERROR );
+      return;
+    }
+  }
+
+  stream_.state = STREAM_STOPPED;
+  MUTEX_UNLOCK( &stream_.mutex );
+}
+
+void RtApiPulse::abortStream( void )
+{
+  PulseAudioHandle *pah = static_cast<PulseAudioHandle*>( stream_.apiHandle );
+
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiPulse::abortStream(): the stream is not open!";
+    error( RtAudioError::INVALID_USE );
+    return;
+  }
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiPulse::abortStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  stream_.state = STREAM_STOPPED;
+  MUTEX_LOCK( &stream_.mutex );
+
+  if ( pah && pah->s_play ) {
+    int pa_error;
+    if ( pa_simple_flush( pah->s_play, &pa_error ) < 0 ) {
+      errorStream_ << "RtApiPulse::abortStream: error flushing output device, " <<
+        pa_strerror( pa_error ) << ".";
+      errorText_ = errorStream_.str();
+      MUTEX_UNLOCK( &stream_.mutex );
+      error( RtAudioError::SYSTEM_ERROR );
+      return;
+    }
+  }
+
+  stream_.state = STREAM_STOPPED;
+  MUTEX_UNLOCK( &stream_.mutex );
+}
+
+bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode,
+                                  unsigned int channels, unsigned int firstChannel,
+                                  unsigned int sampleRate, RtAudioFormat format,
+                                  unsigned int *bufferSize, RtAudio::StreamOptions *options )
+{
+  PulseAudioHandle *pah = 0;
+  unsigned long bufferBytes = 0;
+  pa_sample_spec ss;
+
+  if ( device != 0 ) return false;
+  if ( mode != INPUT && mode != OUTPUT ) return false;
+  if ( channels != 1 && channels != 2 ) {
+    errorText_ = "RtApiPulse::probeDeviceOpen: unsupported number of channels.";
+    return false;
+  }
+  ss.channels = channels;
+
+  if ( firstChannel != 0 ) return false;
+
+  bool sr_found = false;
+  for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr ) {
+    if ( sampleRate == *sr ) {
+      sr_found = true;
+      stream_.sampleRate = sampleRate;
+      ss.rate = sampleRate;
+      break;
+    }
+  }
+  if ( !sr_found ) {
+    errorText_ = "RtApiPulse::probeDeviceOpen: unsupported sample rate.";
+    return false;
+  }
+
+  bool sf_found = 0;
+  for ( const rtaudio_pa_format_mapping_t *sf = supported_sampleformats;
+        sf->rtaudio_format && sf->pa_format != PA_SAMPLE_INVALID; ++sf ) {
+    if ( format == sf->rtaudio_format ) {
+      sf_found = true;
+      stream_.userFormat = sf->rtaudio_format;
+      stream_.deviceFormat[mode] = stream_.userFormat;
+      ss.format = sf->pa_format;
+      break;
+    }
+  }
+  if ( !sf_found ) { // Use internal data format conversion.
+    stream_.userFormat = format;
+    stream_.deviceFormat[mode] = RTAUDIO_FLOAT32;
+    ss.format = PA_SAMPLE_FLOAT32LE;
+  }
+
+  // Set other stream parameters.
+  if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
+  else stream_.userInterleaved = true;
+  stream_.deviceInterleaved[mode] = true;
+  stream_.nBuffers = 1;
+  stream_.doByteSwap[mode] = false;
+  stream_.nUserChannels[mode] = channels;
+  stream_.nDeviceChannels[mode] = channels + firstChannel;
+  stream_.channelOffset[mode] = 0;
+  std::string streamName = "RtAudio";
+
+  // Set flags for buffer conversion.
+  stream_.doConvertBuffer[mode] = false;
+  if ( stream_.userFormat != stream_.deviceFormat[mode] )
+    stream_.doConvertBuffer[mode] = true;
+  if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] )
+    stream_.doConvertBuffer[mode] = true;
+
+  // Allocate necessary internal buffers.
+  bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
+  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
+  if ( stream_.userBuffer[mode] == NULL ) {
+    errorText_ = "RtApiPulse::probeDeviceOpen: error allocating user buffer memory.";
+    goto error;
+  }
+  stream_.bufferSize = *bufferSize;
+
+  if ( stream_.doConvertBuffer[mode] ) {
+
+    bool makeBuffer = true;
+    bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
+    if ( mode == INPUT ) {
+      if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
+        unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
+        if ( bufferBytes <= bytesOut ) makeBuffer = false;
+      }
+    }
+
+    if ( makeBuffer ) {
+      bufferBytes *= *bufferSize;
+      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
+      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
+      if ( stream_.deviceBuffer == NULL ) {
+        errorText_ = "RtApiPulse::probeDeviceOpen: error allocating device buffer memory.";
+        goto error;
+      }
+    }
+  }
+
+  stream_.device[mode] = device;
+
+  // Setup the buffer conversion information structure.
+  if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel );
+
+  if ( !stream_.apiHandle ) {
+    PulseAudioHandle *pah = new PulseAudioHandle;
+    if ( !pah ) {
+      errorText_ = "RtApiPulse::probeDeviceOpen: error allocating memory for handle.";
+      goto error;
+    }
+
+    stream_.apiHandle = pah;
+    if ( pthread_cond_init( &pah->runnable_cv, NULL ) != 0 ) {
+      errorText_ = "RtApiPulse::probeDeviceOpen: error creating condition variable.";
+      goto error;
+    }
+  }
+  pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
+
+  int error;
+  if ( !options->streamName.empty() ) streamName = options->streamName;
+  switch ( mode ) {
+  case INPUT:
+    pa_buffer_attr buffer_attr;
+    buffer_attr.fragsize = bufferBytes;
+    buffer_attr.maxlength = -1;
+
+    pah->s_rec = pa_simple_new( NULL, streamName.c_str(), PA_STREAM_RECORD, NULL, "Record", &ss, NULL, &buffer_attr, &error );
+    if ( !pah->s_rec ) {
+      errorText_ = "RtApiPulse::probeDeviceOpen: error connecting input to PulseAudio server.";
+      goto error;
+    }
+    break;
+  case OUTPUT:
+    pah->s_play = pa_simple_new( NULL, "RtAudio", PA_STREAM_PLAYBACK, NULL, "Playback", &ss, NULL, NULL, &error );
+    if ( !pah->s_play ) {
+      errorText_ = "RtApiPulse::probeDeviceOpen: error connecting output to PulseAudio server.";
+      goto error;
+    }
+    break;
+  default:
+    goto error;
+  }
+
+  if ( stream_.mode == UNINITIALIZED )
+    stream_.mode = mode;
+  else if ( stream_.mode == mode )
+    goto error;
+  else
+    stream_.mode = DUPLEX;
+
+  if ( !stream_.callbackInfo.isRunning ) {
+    stream_.callbackInfo.object = this;
+    stream_.callbackInfo.isRunning = true;
+    if ( pthread_create( &pah->thread, NULL, pulseaudio_callback, (void *)&stream_.callbackInfo) != 0 ) {
+      errorText_ = "RtApiPulse::probeDeviceOpen: error creating thread.";
+      goto error;
+    }
+  }
+
+  stream_.state = STREAM_STOPPED;
+  return true;
+ 
+ error:
+  if ( pah && stream_.callbackInfo.isRunning ) {
+    pthread_cond_destroy( &pah->runnable_cv );
+    delete pah;
+    stream_.apiHandle = 0;
+  }
+
+  for ( int i=0; i<2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  return FAILURE;
+}
+
+//******************** End of __LINUX_PULSE__ *********************//
+#endif
+
+#if defined(__LINUX_OSS__)
+
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/soundcard.h>
+#include <errno.h>
+#include <math.h>
+
+static void *ossCallbackHandler(void * ptr);
+
+// A structure to hold various information related to the OSS API
+// implementation.
+struct OssHandle {
+  int id[2];    // device ids
+  bool xrun[2];
+  bool triggered;
+  pthread_cond_t runnable;
+
+  OssHandle()
+    :triggered(false) { id[0] = 0; id[1] = 0; xrun[0] = false; xrun[1] = false; }
+};
+
+RtApiOss :: RtApiOss()
+{
+  // Nothing to do here.
+}
+
+RtApiOss :: ~RtApiOss()
+{
+  if ( stream_.state != STREAM_CLOSED ) closeStream();
+}
+
+unsigned int RtApiOss :: getDeviceCount( void )
+{
+  int mixerfd = open( "/dev/mixer", O_RDWR, 0 );
+  if ( mixerfd == -1 ) {
+    errorText_ = "RtApiOss::getDeviceCount: error opening '/dev/mixer'.";
+    error( RtAudioError::WARNING );
+    return 0;
+  }
+
+  oss_sysinfo sysinfo;
+  if ( ioctl( mixerfd, SNDCTL_SYSINFO, &sysinfo ) == -1 ) {
+    close( mixerfd );
+    errorText_ = "RtApiOss::getDeviceCount: error getting sysinfo, OSS version >= 4.0 is required.";
+    error( RtAudioError::WARNING );
+    return 0;
+  }
+
+  close( mixerfd );
+  return sysinfo.numaudios;
+}
+
+RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device )
+{
+  RtAudio::DeviceInfo info;
+  info.probed = false;
+
+  int mixerfd = open( "/dev/mixer", O_RDWR, 0 );
+  if ( mixerfd == -1 ) {
+    errorText_ = "RtApiOss::getDeviceInfo: error opening '/dev/mixer'.";
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  oss_sysinfo sysinfo;
+  int result = ioctl( mixerfd, SNDCTL_SYSINFO, &sysinfo );
+  if ( result == -1 ) {
+    close( mixerfd );
+    errorText_ = "RtApiOss::getDeviceInfo: error getting sysinfo, OSS version >= 4.0 is required.";
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  unsigned nDevices = sysinfo.numaudios;
+  if ( nDevices == 0 ) {
+    close( mixerfd );
+    errorText_ = "RtApiOss::getDeviceInfo: no devices found!";
+    error( RtAudioError::INVALID_USE );
+    return info;
+  }
+
+  if ( device >= nDevices ) {
+    close( mixerfd );
+    errorText_ = "RtApiOss::getDeviceInfo: device ID is invalid!";
+    error( RtAudioError::INVALID_USE );
+    return info;
+  }
+
+  oss_audioinfo ainfo;
+  ainfo.dev = device;
+  result = ioctl( mixerfd, SNDCTL_AUDIOINFO, &ainfo );
+  close( mixerfd );
+  if ( result == -1 ) {
+    errorStream_ << "RtApiOss::getDeviceInfo: error getting device (" << ainfo.name << ") info.";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // Probe channels
+  if ( ainfo.caps & PCM_CAP_OUTPUT ) info.outputChannels = ainfo.max_channels;
+  if ( ainfo.caps & PCM_CAP_INPUT ) info.inputChannels = ainfo.max_channels;
+  if ( ainfo.caps & PCM_CAP_DUPLEX ) {
+    if ( info.outputChannels > 0 && info.inputChannels > 0 && ainfo.caps & PCM_CAP_DUPLEX )
+      info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
+  }
+
+  // Probe data formats ... do for input
+  unsigned long mask = ainfo.iformats;
+  if ( mask & AFMT_S16_LE || mask & AFMT_S16_BE )
+    info.nativeFormats |= RTAUDIO_SINT16;
+  if ( mask & AFMT_S8 )
+    info.nativeFormats |= RTAUDIO_SINT8;
+  if ( mask & AFMT_S32_LE || mask & AFMT_S32_BE )
+    info.nativeFormats |= RTAUDIO_SINT32;
+  if ( mask & AFMT_FLOAT )
+    info.nativeFormats |= RTAUDIO_FLOAT32;
+  if ( mask & AFMT_S24_LE || mask & AFMT_S24_BE )
+    info.nativeFormats |= RTAUDIO_SINT24;
+
+  // Check that we have at least one supported format
+  if ( info.nativeFormats == 0 ) {
+    errorStream_ << "RtApiOss::getDeviceInfo: device (" << ainfo.name << ") data format not supported by RtAudio.";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+    return info;
+  }
+
+  // Probe the supported sample rates.
+  info.sampleRates.clear();
+  if ( ainfo.nrates ) {
+    for ( unsigned int i=0; i<ainfo.nrates; i++ ) {
+      for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
+        if ( ainfo.rates[i] == SAMPLE_RATES[k] ) {
+          info.sampleRates.push_back( SAMPLE_RATES[k] );
+          break;
+        }
+      }
+    }
+  }
+  else {
+    // Check min and max rate values;
+    for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
+      if ( ainfo.min_rate <= (int) SAMPLE_RATES[k] && ainfo.max_rate >= (int) SAMPLE_RATES[k] )
+        info.sampleRates.push_back( SAMPLE_RATES[k] );
+    }
+  }
+
+  if ( info.sampleRates.size() == 0 ) {
+    errorStream_ << "RtApiOss::getDeviceInfo: no supported sample rates found for device (" << ainfo.name << ").";
+    errorText_ = errorStream_.str();
+    error( RtAudioError::WARNING );
+  }
+  else {
+    info.probed = true;
+    info.name = ainfo.name;
+  }
+
+  return info;
+}
+
+
+bool RtApiOss :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
+                                  unsigned int firstChannel, unsigned int sampleRate,
+                                  RtAudioFormat format, unsigned int *bufferSize,
+                                  RtAudio::StreamOptions *options )
+{
+  int mixerfd = open( "/dev/mixer", O_RDWR, 0 );
+  if ( mixerfd == -1 ) {
+    errorText_ = "RtApiOss::probeDeviceOpen: error opening '/dev/mixer'.";
+    return FAILURE;
+  }
+
+  oss_sysinfo sysinfo;
+  int result = ioctl( mixerfd, SNDCTL_SYSINFO, &sysinfo );
+  if ( result == -1 ) {
+    close( mixerfd );
+    errorText_ = "RtApiOss::probeDeviceOpen: error getting sysinfo, OSS version >= 4.0 is required.";
+    return FAILURE;
+  }
+
+  unsigned nDevices = sysinfo.numaudios;
+  if ( nDevices == 0 ) {
+    // This should not happen because a check is made before this function is called.
+    close( mixerfd );
+    errorText_ = "RtApiOss::probeDeviceOpen: no devices found!";
+    return FAILURE;
+  }
+
+  if ( device >= nDevices ) {
+    // This should not happen because a check is made before this function is called.
+    close( mixerfd );
+    errorText_ = "RtApiOss::probeDeviceOpen: device ID is invalid!";
+    return FAILURE;
+  }
+
+  oss_audioinfo ainfo;
+  ainfo.dev = device;
+  result = ioctl( mixerfd, SNDCTL_AUDIOINFO, &ainfo );
+  close( mixerfd );
+  if ( result == -1 ) {
+    errorStream_ << "RtApiOss::getDeviceInfo: error getting device (" << ainfo.name << ") info.";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Check if device supports input or output
+  if ( ( mode == OUTPUT && !( ainfo.caps & PCM_CAP_OUTPUT ) ) ||
+       ( mode == INPUT && !( ainfo.caps & PCM_CAP_INPUT ) ) ) {
+    if ( mode == OUTPUT )
+      errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support output.";
+    else
+      errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support input.";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  int flags = 0;
+  OssHandle *handle = (OssHandle *) stream_.apiHandle;
+  if ( mode == OUTPUT )
+    flags |= O_WRONLY;
+  else { // mode == INPUT
+    if (stream_.mode == OUTPUT && stream_.device[0] == device) {
+      // We just set the same device for playback ... close and reopen for duplex (OSS only).
+      close( handle->id[0] );
+      handle->id[0] = 0;
+      if ( !( ainfo.caps & PCM_CAP_DUPLEX ) ) {
+        errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support duplex mode.";
+        errorText_ = errorStream_.str();
+        return FAILURE;
+      }
+      // Check that the number previously set channels is the same.
+      if ( stream_.nUserChannels[0] != channels ) {
+        errorStream_ << "RtApiOss::probeDeviceOpen: input/output channels must be equal for OSS duplex device (" << ainfo.name << ").";
+        errorText_ = errorStream_.str();
+        return FAILURE;
+      }
+      flags |= O_RDWR;
+    }
+    else
+      flags |= O_RDONLY;
+  }
+
+  // Set exclusive access if specified.
+  if ( options && options->flags & RTAUDIO_HOG_DEVICE ) flags |= O_EXCL;
+
+  // Try to open the device.
+  int fd;
+  fd = open( ainfo.devnode, flags, 0 );
+  if ( fd == -1 ) {
+    if ( errno == EBUSY )
+      errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") is busy.";
+    else
+      errorStream_ << "RtApiOss::probeDeviceOpen: error opening device (" << ainfo.name << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // For duplex operation, specifically set this mode (this doesn't seem to work).
+  /*
+    if ( flags | O_RDWR ) {
+    result = ioctl( fd, SNDCTL_DSP_SETDUPLEX, NULL );
+    if ( result == -1) {
+    errorStream_ << "RtApiOss::probeDeviceOpen: error setting duplex mode for device (" << ainfo.name << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+    }
+    }
+  */
+
+  // Check the device channel support.
+  stream_.nUserChannels[mode] = channels;
+  if ( ainfo.max_channels < (int)(channels + firstChannel) ) {
+    close( fd );
+    errorStream_ << "RtApiOss::probeDeviceOpen: the device (" << ainfo.name << ") does not support requested channel parameters.";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Set the number of channels.
+  int deviceChannels = channels + firstChannel;
+  result = ioctl( fd, SNDCTL_DSP_CHANNELS, &deviceChannels );
+  if ( result == -1 || deviceChannels < (int)(channels + firstChannel) ) {
+    close( fd );
+    errorStream_ << "RtApiOss::probeDeviceOpen: error setting channel parameters on device (" << ainfo.name << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+  stream_.nDeviceChannels[mode] = deviceChannels;
+
+  // Get the data format mask
+  int mask;
+  result = ioctl( fd, SNDCTL_DSP_GETFMTS, &mask );
+  if ( result == -1 ) {
+    close( fd );
+    errorStream_ << "RtApiOss::probeDeviceOpen: error getting device (" << ainfo.name << ") data formats.";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Determine how to set the device format.
+  stream_.userFormat = format;
+  int deviceFormat = -1;
+  stream_.doByteSwap[mode] = false;
+  if ( format == RTAUDIO_SINT8 ) {
+    if ( mask & AFMT_S8 ) {
+      deviceFormat = AFMT_S8;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT8;
+    }
+  }
+  else if ( format == RTAUDIO_SINT16 ) {
+    if ( mask & AFMT_S16_NE ) {
+      deviceFormat = AFMT_S16_NE;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT16;
+    }
+    else if ( mask & AFMT_S16_OE ) {
+      deviceFormat = AFMT_S16_OE;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT16;
+      stream_.doByteSwap[mode] = true;
+    }
+  }
+  else if ( format == RTAUDIO_SINT24 ) {
+    if ( mask & AFMT_S24_NE ) {
+      deviceFormat = AFMT_S24_NE;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT24;
+    }
+    else if ( mask & AFMT_S24_OE ) {
+      deviceFormat = AFMT_S24_OE;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT24;
+      stream_.doByteSwap[mode] = true;
+    }
+  }
+  else if ( format == RTAUDIO_SINT32 ) {
+    if ( mask & AFMT_S32_NE ) {
+      deviceFormat = AFMT_S32_NE;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT32;
+    }
+    else if ( mask & AFMT_S32_OE ) {
+      deviceFormat = AFMT_S32_OE;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT32;
+      stream_.doByteSwap[mode] = true;
+    }
+  }
+
+  if ( deviceFormat == -1 ) {
+    // The user requested format is not natively supported by the device.
+    if ( mask & AFMT_S16_NE ) {
+      deviceFormat = AFMT_S16_NE;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT16;
+    }
+    else if ( mask & AFMT_S32_NE ) {
+      deviceFormat = AFMT_S32_NE;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT32;
+    }
+    else if ( mask & AFMT_S24_NE ) {
+      deviceFormat = AFMT_S24_NE;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT24;
+    }
+    else if ( mask & AFMT_S16_OE ) {
+      deviceFormat = AFMT_S16_OE;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT16;
+      stream_.doByteSwap[mode] = true;
+    }
+    else if ( mask & AFMT_S32_OE ) {
+      deviceFormat = AFMT_S32_OE;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT32;
+      stream_.doByteSwap[mode] = true;
+    }
+    else if ( mask & AFMT_S24_OE ) {
+      deviceFormat = AFMT_S24_OE;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT24;
+      stream_.doByteSwap[mode] = true;
+    }
+    else if ( mask & AFMT_S8) {
+      deviceFormat = AFMT_S8;
+      stream_.deviceFormat[mode] = RTAUDIO_SINT8;
+    }
+  }
+
+  if ( stream_.deviceFormat[mode] == 0 ) {
+    // This really shouldn't happen ...
+    close( fd );
+    errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") data format not supported by RtAudio.";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Set the data format.
+  int temp = deviceFormat;
+  result = ioctl( fd, SNDCTL_DSP_SETFMT, &deviceFormat );
+  if ( result == -1 || deviceFormat != temp ) {
+    close( fd );
+    errorStream_ << "RtApiOss::probeDeviceOpen: error setting data format on device (" << ainfo.name << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Attempt to set the buffer size.  According to OSS, the minimum
+  // number of buffers is two.  The supposed minimum buffer size is 16
+  // bytes, so that will be our lower bound.  The argument to this
+  // call is in the form 0xMMMMSSSS (hex), where the buffer size (in
+  // bytes) is given as 2^SSSS and the number of buffers as 2^MMMM.
+  // We'll check the actual value used near the end of the setup
+  // procedure.
+  int ossBufferBytes = *bufferSize * formatBytes( stream_.deviceFormat[mode] ) * deviceChannels;
+  if ( ossBufferBytes < 16 ) ossBufferBytes = 16;
+  int buffers = 0;
+  if ( options ) buffers = options->numberOfBuffers;
+  if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) buffers = 2;
+  if ( buffers < 2 ) buffers = 3;
+  temp = ((int) buffers << 16) + (int)( log10( (double)ossBufferBytes ) / log10( 2.0 ) );
+  result = ioctl( fd, SNDCTL_DSP_SETFRAGMENT, &temp );
+  if ( result == -1 ) {
+    close( fd );
+    errorStream_ << "RtApiOss::probeDeviceOpen: error setting buffer size on device (" << ainfo.name << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+  stream_.nBuffers = buffers;
+
+  // Save buffer size (in sample frames).
+  *bufferSize = ossBufferBytes / ( formatBytes(stream_.deviceFormat[mode]) * deviceChannels );
+  stream_.bufferSize = *bufferSize;
+
+  // Set the sample rate.
+  int srate = sampleRate;
+  result = ioctl( fd, SNDCTL_DSP_SPEED, &srate );
+  if ( result == -1 ) {
+    close( fd );
+    errorStream_ << "RtApiOss::probeDeviceOpen: error setting sample rate (" << sampleRate << ") on device (" << ainfo.name << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+
+  // Verify the sample rate setup worked.
+  if ( abs( srate - sampleRate ) > 100 ) {
+    close( fd );
+    errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support sample rate (" << sampleRate << ").";
+    errorText_ = errorStream_.str();
+    return FAILURE;
+  }
+  stream_.sampleRate = sampleRate;
+
+  if ( mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] == device) {
+    // We're doing duplex setup here.
+    stream_.deviceFormat[0] = stream_.deviceFormat[1];
+    stream_.nDeviceChannels[0] = deviceChannels;
+  }
+
+  // Set interleaving parameters.
+  stream_.userInterleaved = true;
+  stream_.deviceInterleaved[mode] =  true;
+  if ( options && options->flags & RTAUDIO_NONINTERLEAVED )
+    stream_.userInterleaved = false;
+
+  // Set flags for buffer conversion
+  stream_.doConvertBuffer[mode] = false;
+  if ( stream_.userFormat != stream_.deviceFormat[mode] )
+    stream_.doConvertBuffer[mode] = true;
+  if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] )
+    stream_.doConvertBuffer[mode] = true;
+  if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
+       stream_.nUserChannels[mode] > 1 )
+    stream_.doConvertBuffer[mode] = true;
+
+  // Allocate the stream handles if necessary and then save.
+  if ( stream_.apiHandle == 0 ) {
+    try {
+      handle = new OssHandle;
+    }
+    catch ( std::bad_alloc& ) {
+      errorText_ = "RtApiOss::probeDeviceOpen: error allocating OssHandle memory.";
+      goto error;
+    }
+
+    if ( pthread_cond_init( &handle->runnable, NULL ) ) {
+      errorText_ = "RtApiOss::probeDeviceOpen: error initializing pthread condition variable.";
+      goto error;
+    }
+
+    stream_.apiHandle = (void *) handle;
+  }
+  else {
+    handle = (OssHandle *) stream_.apiHandle;
+  }
+  handle->id[mode] = fd;
+
+  // Allocate necessary internal buffers.
+  unsigned long bufferBytes;
+  bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
+  stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
+  if ( stream_.userBuffer[mode] == NULL ) {
+    errorText_ = "RtApiOss::probeDeviceOpen: error allocating user buffer memory.";
+    goto error;
+  }
+
+  if ( stream_.doConvertBuffer[mode] ) {
+
+    bool makeBuffer = true;
+    bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
+    if ( mode == INPUT ) {
+      if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
+        unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
+        if ( bufferBytes <= bytesOut ) makeBuffer = false;
+      }
+    }
+
+    if ( makeBuffer ) {
+      bufferBytes *= *bufferSize;
+      if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
+      stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
+      if ( stream_.deviceBuffer == NULL ) {
+        errorText_ = "RtApiOss::probeDeviceOpen: error allocating device buffer memory.";
+        goto error;
+      }
+    }
+  }
+
+  stream_.device[mode] = device;
+  stream_.state = STREAM_STOPPED;
+
+  // Setup the buffer conversion information structure.
+  if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel );
+
+  // Setup thread if necessary.
+  if ( stream_.mode == OUTPUT && mode == INPUT ) {
+    // We had already set up an output stream.
+    stream_.mode = DUPLEX;
+    if ( stream_.device[0] == device ) handle->id[0] = fd;
+  }
+  else {
+    stream_.mode = mode;
+
+    // Setup callback thread.
+    stream_.callbackInfo.object = (void *) this;
+
+    // Set the thread attributes for joinable and realtime scheduling
+    // priority.  The higher priority will only take affect if the
+    // program is run as root or suid.
+    pthread_attr_t attr;
+    pthread_attr_init( &attr );
+    pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
+#ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread)
+    if ( options && options->flags & RTAUDIO_SCHEDULE_REALTIME ) {
+      struct sched_param param;
+      int priority = options->priority;
+      int min = sched_get_priority_min( SCHED_RR );
+      int max = sched_get_priority_max( SCHED_RR );
+      if ( priority < min ) priority = min;
+      else if ( priority > max ) priority = max;
+      param.sched_priority = priority;
+      pthread_attr_setschedparam( &attr, &param );
+      pthread_attr_setschedpolicy( &attr, SCHED_RR );
+    }
+    else
+      pthread_attr_setschedpolicy( &attr, SCHED_OTHER );
+#else
+    pthread_attr_setschedpolicy( &attr, SCHED_OTHER );
+#endif
+
+    stream_.callbackInfo.isRunning = true;
+    result = pthread_create( &stream_.callbackInfo.thread, &attr, ossCallbackHandler, &stream_.callbackInfo );
+    pthread_attr_destroy( &attr );
+    if ( result ) {
+      stream_.callbackInfo.isRunning = false;
+      errorText_ = "RtApiOss::error creating callback thread!";
+      goto error;
+    }
+  }
+
+  return SUCCESS;
+
+ error:
+  if ( handle ) {
+    pthread_cond_destroy( &handle->runnable );
+    if ( handle->id[0] ) close( handle->id[0] );
+    if ( handle->id[1] ) close( handle->id[1] );
+    delete handle;
+    stream_.apiHandle = 0;
+  }
+
+  for ( int i=0; i<2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  return FAILURE;
+}
+
+void RtApiOss :: closeStream()
+{
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiOss::closeStream(): no open stream to close!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  OssHandle *handle = (OssHandle *) stream_.apiHandle;
+  stream_.callbackInfo.isRunning = false;
+  MUTEX_LOCK( &stream_.mutex );
+  if ( stream_.state == STREAM_STOPPED )
+    pthread_cond_signal( &handle->runnable );
+  MUTEX_UNLOCK( &stream_.mutex );
+  pthread_join( stream_.callbackInfo.thread, NULL );
+
+  if ( stream_.state == STREAM_RUNNING ) {
+    if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX )
+      ioctl( handle->id[0], SNDCTL_DSP_HALT, 0 );
+    else
+      ioctl( handle->id[1], SNDCTL_DSP_HALT, 0 );
+    stream_.state = STREAM_STOPPED;
+  }
+
+  if ( handle ) {
+    pthread_cond_destroy( &handle->runnable );
+    if ( handle->id[0] ) close( handle->id[0] );
+    if ( handle->id[1] ) close( handle->id[1] );
+    delete handle;
+    stream_.apiHandle = 0;
+  }
+
+  for ( int i=0; i<2; i++ ) {
+    if ( stream_.userBuffer[i] ) {
+      free( stream_.userBuffer[i] );
+      stream_.userBuffer[i] = 0;
+    }
+  }
+
+  if ( stream_.deviceBuffer ) {
+    free( stream_.deviceBuffer );
+    stream_.deviceBuffer = 0;
+  }
+
+  stream_.mode = UNINITIALIZED;
+  stream_.state = STREAM_CLOSED;
+}
+
+void RtApiOss :: startStream()
+{
+  verifyStream();
+  if ( stream_.state == STREAM_RUNNING ) {
+    errorText_ = "RtApiOss::startStream(): the stream is already running!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  MUTEX_LOCK( &stream_.mutex );
+
+  stream_.state = STREAM_RUNNING;
+
+  // No need to do anything else here ... OSS automatically starts
+  // when fed samples.
+
+  MUTEX_UNLOCK( &stream_.mutex );
+
+  OssHandle *handle = (OssHandle *) stream_.apiHandle;
+  pthread_cond_signal( &handle->runnable );
+}
+
+void RtApiOss :: stopStream()
+{
+  verifyStream();
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiOss::stopStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  MUTEX_LOCK( &stream_.mutex );
+
+  // The state might change while waiting on a mutex.
+  if ( stream_.state == STREAM_STOPPED ) {
+    MUTEX_UNLOCK( &stream_.mutex );
+    return;
+  }
+
+  int result = 0;
+  OssHandle *handle = (OssHandle *) stream_.apiHandle;
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+
+    // Flush the output with zeros a few times.
+    char *buffer;
+    int samples;
+    RtAudioFormat format;
+
+    if ( stream_.doConvertBuffer[0] ) {
+      buffer = stream_.deviceBuffer;
+      samples = stream_.bufferSize * stream_.nDeviceChannels[0];
+      format = stream_.deviceFormat[0];
+    }
+    else {
+      buffer = stream_.userBuffer[0];
+      samples = stream_.bufferSize * stream_.nUserChannels[0];
+      format = stream_.userFormat;
+    }
+
+    memset( buffer, 0, samples * formatBytes(format) );
+    for ( unsigned int i=0; i<stream_.nBuffers+1; i++ ) {
+      result = write( handle->id[0], buffer, samples * formatBytes(format) );
+      if ( result == -1 ) {
+        errorText_ = "RtApiOss::stopStream: audio write error.";
+        error( RtAudioError::WARNING );
+      }
+    }
+
+    result = ioctl( handle->id[0], SNDCTL_DSP_HALT, 0 );
+    if ( result == -1 ) {
+      errorStream_ << "RtApiOss::stopStream: system error stopping callback procedure on device (" << stream_.device[0] << ").";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+    handle->triggered = false;
+  }
+
+  if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && handle->id[0] != handle->id[1] ) ) {
+    result = ioctl( handle->id[1], SNDCTL_DSP_HALT, 0 );
+    if ( result == -1 ) {
+      errorStream_ << "RtApiOss::stopStream: system error stopping input callback procedure on device (" << stream_.device[0] << ").";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+  }
+
+ unlock:
+  stream_.state = STREAM_STOPPED;
+  MUTEX_UNLOCK( &stream_.mutex );
+
+  if ( result != -1 ) return;
+  error( RtAudioError::SYSTEM_ERROR );
+}
+
+void RtApiOss :: abortStream()
+{
+  verifyStream();
+  if ( stream_.state == STREAM_STOPPED ) {
+    errorText_ = "RtApiOss::abortStream(): the stream is already stopped!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  MUTEX_LOCK( &stream_.mutex );
+
+  // The state might change while waiting on a mutex.
+  if ( stream_.state == STREAM_STOPPED ) {
+    MUTEX_UNLOCK( &stream_.mutex );
+    return;
+  }
+
+  int result = 0;
+  OssHandle *handle = (OssHandle *) stream_.apiHandle;
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+    result = ioctl( handle->id[0], SNDCTL_DSP_HALT, 0 );
+    if ( result == -1 ) {
+      errorStream_ << "RtApiOss::abortStream: system error stopping callback procedure on device (" << stream_.device[0] << ").";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+    handle->triggered = false;
+  }
+
+  if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && handle->id[0] != handle->id[1] ) ) {
+    result = ioctl( handle->id[1], SNDCTL_DSP_HALT, 0 );
+    if ( result == -1 ) {
+      errorStream_ << "RtApiOss::abortStream: system error stopping input callback procedure on device (" << stream_.device[0] << ").";
+      errorText_ = errorStream_.str();
+      goto unlock;
+    }
+  }
+
+ unlock:
+  stream_.state = STREAM_STOPPED;
+  MUTEX_UNLOCK( &stream_.mutex );
+
+  if ( result != -1 ) return;
+  error( RtAudioError::SYSTEM_ERROR );
+}
+
+void RtApiOss :: callbackEvent()
+{
+  OssHandle *handle = (OssHandle *) stream_.apiHandle;
+  if ( stream_.state == STREAM_STOPPED ) {
+    MUTEX_LOCK( &stream_.mutex );
+    pthread_cond_wait( &handle->runnable, &stream_.mutex );
+    if ( stream_.state != STREAM_RUNNING ) {
+      MUTEX_UNLOCK( &stream_.mutex );
+      return;
+    }
+    MUTEX_UNLOCK( &stream_.mutex );
+  }
+
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApiOss::callbackEvent(): the stream is closed ... this shouldn't happen!";
+    error( RtAudioError::WARNING );
+    return;
+  }
+
+  // Invoke user callback to get fresh output data.
+  int doStopStream = 0;
+  RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback;
+  double streamTime = getStreamTime();
+  RtAudioStreamStatus status = 0;
+  if ( stream_.mode != INPUT && handle->xrun[0] == true ) {
+    status |= RTAUDIO_OUTPUT_UNDERFLOW;
+    handle->xrun[0] = false;
+  }
+  if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) {
+    status |= RTAUDIO_INPUT_OVERFLOW;
+    handle->xrun[1] = false;
+  }
+  doStopStream = callback( stream_.userBuffer[0], stream_.userBuffer[1],
+                           stream_.bufferSize, streamTime, status, stream_.callbackInfo.userData );
+  if ( doStopStream == 2 ) {
+    this->abortStream();
+    return;
+  }
+
+  MUTEX_LOCK( &stream_.mutex );
+
+  // The state might change while waiting on a mutex.
+  if ( stream_.state == STREAM_STOPPED ) goto unlock;
+
+  int result;
+  char *buffer;
+  int samples;
+  RtAudioFormat format;
+
+  if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+
+    // Setup parameters and do buffer conversion if necessary.
+    if ( stream_.doConvertBuffer[0] ) {
+      buffer = stream_.deviceBuffer;
+      convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] );
+      samples = stream_.bufferSize * stream_.nDeviceChannels[0];
+      format = stream_.deviceFormat[0];
+    }
+    else {
+      buffer = stream_.userBuffer[0];
+      samples = stream_.bufferSize * stream_.nUserChannels[0];
+      format = stream_.userFormat;
+    }
+
+    // Do byte swapping if necessary.
+    if ( stream_.doByteSwap[0] )
+      byteSwapBuffer( buffer, samples, format );
+
+    if ( stream_.mode == DUPLEX && handle->triggered == false ) {
+      int trig = 0;
+      ioctl( handle->id[0], SNDCTL_DSP_SETTRIGGER, &trig );
+      result = write( handle->id[0], buffer, samples * formatBytes(format) );
+      trig = PCM_ENABLE_INPUT|PCM_ENABLE_OUTPUT;
+      ioctl( handle->id[0], SNDCTL_DSP_SETTRIGGER, &trig );
+      handle->triggered = true;
+    }
+    else
+      // Write samples to device.
+      result = write( handle->id[0], buffer, samples * formatBytes(format) );
+
+    if ( result == -1 ) {
+      // We'll assume this is an underrun, though there isn't a
+      // specific means for determining that.
+      handle->xrun[0] = true;
+      errorText_ = "RtApiOss::callbackEvent: audio write error.";
+      error( RtAudioError::WARNING );
+      // Continue on to input section.
+    }
+  }
+
+  if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
+
+    // Setup parameters.
+    if ( stream_.doConvertBuffer[1] ) {
+      buffer = stream_.deviceBuffer;
+      samples = stream_.bufferSize * stream_.nDeviceChannels[1];
+      format = stream_.deviceFormat[1];
+    }
+    else {
+      buffer = stream_.userBuffer[1];
+      samples = stream_.bufferSize * stream_.nUserChannels[1];
+      format = stream_.userFormat;
+    }
+
+    // Read samples from device.
+    result = read( handle->id[1], buffer, samples * formatBytes(format) );
+
+    if ( result == -1 ) {
+      // We'll assume this is an overrun, though there isn't a
+      // specific means for determining that.
+      handle->xrun[1] = true;
+      errorText_ = "RtApiOss::callbackEvent: audio read error.";
+      error( RtAudioError::WARNING );
+      goto unlock;
+    }
+
+    // Do byte swapping if necessary.
+    if ( stream_.doByteSwap[1] )
+      byteSwapBuffer( buffer, samples, format );
+
+    // Do buffer conversion if necessary.
+    if ( stream_.doConvertBuffer[1] )
+      convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
+  }
+
+ unlock:
+  MUTEX_UNLOCK( &stream_.mutex );
+
+  RtApi::tickStreamTime();
+  if ( doStopStream == 1 ) this->stopStream();
+}
+
+static void *ossCallbackHandler( void *ptr )
+{
+  CallbackInfo *info = (CallbackInfo *) ptr;
+  RtApiOss *object = (RtApiOss *) info->object;
+  bool *isRunning = &info->isRunning;
+
+  while ( *isRunning == true ) {
+    pthread_testcancel();
+    object->callbackEvent();
+  }
+
+  pthread_exit( NULL );
+}
+
+//******************** End of __LINUX_OSS__ *********************//
+#endif
+
+
+// *************************************************** //
+//
+// Protected common (OS-independent) RtAudio methods.
+//
+// *************************************************** //
+
+// This method can be modified to control the behavior of error
+// message printing.
+void RtApi :: error( RtAudioError::Type type )
+{
+  errorStream_.str(""); // clear the ostringstream
+
+  RtAudioErrorCallback errorCallback = (RtAudioErrorCallback) stream_.callbackInfo.errorCallback;
+  if ( errorCallback ) {
+    // abortStream() can generate new error messages. Ignore them. Just keep original one.
+
+    if ( firstErrorOccurred_ )
+      return;
+
+    firstErrorOccurred_ = true;
+    const std::string errorMessage = errorText_;
+
+    if ( type != RtAudioError::WARNING && stream_.state != STREAM_STOPPED) {
+      stream_.callbackInfo.isRunning = false; // exit from the thread
+      abortStream();
+    }
+
+    errorCallback( type, errorMessage );
+    firstErrorOccurred_ = false;
+    return;
+  }
+
+  if ( type == RtAudioError::WARNING && showWarnings_ == true )
+    std::cerr << '\n' << errorText_ << "\n\n";
+  else if ( type != RtAudioError::WARNING )
+    throw( RtAudioError( errorText_, type ) );
+}
+
+void RtApi :: verifyStream()
+{
+  if ( stream_.state == STREAM_CLOSED ) {
+    errorText_ = "RtApi:: a stream is not open!";
+    error( RtAudioError::INVALID_USE );
+  }
+}
+
+void RtApi :: clearStreamInfo()
+{
+  stream_.mode = UNINITIALIZED;
+  stream_.state = STREAM_CLOSED;
+  stream_.sampleRate = 0;
+  stream_.bufferSize = 0;
+  stream_.nBuffers = 0;
+  stream_.userFormat = 0;
+  stream_.userInterleaved = true;
+  stream_.streamTime = 0.0;
+  stream_.apiHandle = 0;
+  stream_.deviceBuffer = 0;
+  stream_.callbackInfo.callback = 0;
+  stream_.callbackInfo.userData = 0;
+  stream_.callbackInfo.isRunning = false;
+  stream_.callbackInfo.errorCallback = 0;
+  for ( int i=0; i<2; i++ ) {
+    stream_.device[i] = 11111;
+    stream_.doConvertBuffer[i] = false;
+    stream_.deviceInterleaved[i] = true;
+    stream_.doByteSwap[i] = false;
+    stream_.nUserChannels[i] = 0;
+    stream_.nDeviceChannels[i] = 0;
+    stream_.channelOffset[i] = 0;
+    stream_.deviceFormat[i] = 0;
+    stream_.latency[i] = 0;
+    stream_.userBuffer[i] = 0;
+    stream_.convertInfo[i].channels = 0;
+    stream_.convertInfo[i].inJump = 0;
+    stream_.convertInfo[i].outJump = 0;
+    stream_.convertInfo[i].inFormat = 0;
+    stream_.convertInfo[i].outFormat = 0;
+    stream_.convertInfo[i].inOffset.clear();
+    stream_.convertInfo[i].outOffset.clear();
+  }
+}
+
+unsigned int RtApi :: formatBytes( RtAudioFormat format )
+{
+  if ( format == RTAUDIO_SINT16 )
+    return 2;
+  else if ( format == RTAUDIO_SINT32 || format == RTAUDIO_FLOAT32 )
+    return 4;
+  else if ( format == RTAUDIO_FLOAT64 )
+    return 8;
+  else if ( format == RTAUDIO_SINT24 )
+    return 3;
+  else if ( format == RTAUDIO_SINT8 )
+    return 1;
+
+  errorText_ = "RtApi::formatBytes: undefined format.";
+  error( RtAudioError::WARNING );
+
+  return 0;
+}
+
+void RtApi :: setConvertInfo( StreamMode mode, unsigned int firstChannel )
+{
+  if ( mode == INPUT ) { // convert device to user buffer
+    stream_.convertInfo[mode].inJump = stream_.nDeviceChannels[1];
+    stream_.convertInfo[mode].outJump = stream_.nUserChannels[1];
+    stream_.convertInfo[mode].inFormat = stream_.deviceFormat[1];
+    stream_.convertInfo[mode].outFormat = stream_.userFormat;
+  }
+  else { // convert user to device buffer
+    stream_.convertInfo[mode].inJump = stream_.nUserChannels[0];
+    stream_.convertInfo[mode].outJump = stream_.nDeviceChannels[0];
+    stream_.convertInfo[mode].inFormat = stream_.userFormat;
+    stream_.convertInfo[mode].outFormat = stream_.deviceFormat[0];
+  }
+
+  if ( stream_.convertInfo[mode].inJump < stream_.convertInfo[mode].outJump )
+    stream_.convertInfo[mode].channels = stream_.convertInfo[mode].inJump;
+  else
+    stream_.convertInfo[mode].channels = stream_.convertInfo[mode].outJump;
+
+  // Set up the interleave/deinterleave offsets.
+  if ( stream_.deviceInterleaved[mode] != stream_.userInterleaved ) {
+    if ( ( mode == OUTPUT && stream_.deviceInterleaved[mode] ) ||
+         ( mode == INPUT && stream_.userInterleaved ) ) {
+      for ( int k=0; k<stream_.convertInfo[mode].channels; k++ ) {
+        stream_.convertInfo[mode].inOffset.push_back( k * stream_.bufferSize );
+        stream_.convertInfo[mode].outOffset.push_back( k );
+        stream_.convertInfo[mode].inJump = 1;
+      }
+    }
+    else {
+      for ( int k=0; k<stream_.convertInfo[mode].channels; k++ ) {
+        stream_.convertInfo[mode].inOffset.push_back( k );
+        stream_.convertInfo[mode].outOffset.push_back( k * stream_.bufferSize );
+        stream_.convertInfo[mode].outJump = 1;
+      }
+    }
+  }
+  else { // no (de)interleaving
+    if ( stream_.userInterleaved ) {
+      for ( int k=0; k<stream_.convertInfo[mode].channels; k++ ) {
+        stream_.convertInfo[mode].inOffset.push_back( k );
+        stream_.convertInfo[mode].outOffset.push_back( k );
+      }
+    }
+    else {
+      for ( int k=0; k<stream_.convertInfo[mode].channels; k++ ) {
+        stream_.convertInfo[mode].inOffset.push_back( k * stream_.bufferSize );
+        stream_.convertInfo[mode].outOffset.push_back( k * stream_.bufferSize );
+        stream_.convertInfo[mode].inJump = 1;
+        stream_.convertInfo[mode].outJump = 1;
+      }
+    }
+  }
+
+  // Add channel offset.
+  if ( firstChannel > 0 ) {
+    if ( stream_.deviceInterleaved[mode] ) {
+      if ( mode == OUTPUT ) {
+        for ( int k=0; k<stream_.convertInfo[mode].channels; k++ )
+          stream_.convertInfo[mode].outOffset[k] += firstChannel;
+      }
+      else {
+        for ( int k=0; k<stream_.convertInfo[mode].channels; k++ )
+          stream_.convertInfo[mode].inOffset[k] += firstChannel;
+      }
+    }
+    else {
+      if ( mode == OUTPUT ) {
+        for ( int k=0; k<stream_.convertInfo[mode].channels; k++ )
+          stream_.convertInfo[mode].outOffset[k] += ( firstChannel * stream_.bufferSize );
+      }
+      else {
+        for ( int k=0; k<stream_.convertInfo[mode].channels; k++ )
+          stream_.convertInfo[mode].inOffset[k] += ( firstChannel  * stream_.bufferSize );
+      }
+    }
+  }
+}
+
+void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info )
+{
+  // This function does format conversion, input/output channel compensation, and
+  // data interleaving/deinterleaving.  24-bit integers are assumed to occupy
+  // the lower three bytes of a 32-bit integer.
+
+  // Clear our device buffer when in/out duplex device channels are different
+  if ( outBuffer == stream_.deviceBuffer && stream_.mode == DUPLEX &&
+       ( stream_.nDeviceChannels[0] < stream_.nDeviceChannels[1] ) )
+    memset( outBuffer, 0, stream_.bufferSize * info.outJump * formatBytes( info.outFormat ) );
+
+  int j;
+  if (info.outFormat == RTAUDIO_FLOAT64) {
+    Float64 scale;
+    Float64 *out = (Float64 *)outBuffer;
+
+    if (info.inFormat == RTAUDIO_SINT8) {
+      signed char *in = (signed char *)inBuffer;
+      scale = 1.0 / 127.5;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Float64) in[info.inOffset[j]];
+          out[info.outOffset[j]] += 0.5;
+          out[info.outOffset[j]] *= scale;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT16) {
+      Int16 *in = (Int16 *)inBuffer;
+      scale = 1.0 / 32767.5;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Float64) in[info.inOffset[j]];
+          out[info.outOffset[j]] += 0.5;
+          out[info.outOffset[j]] *= scale;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT24) {
+      Int24 *in = (Int24 *)inBuffer;
+      scale = 1.0 / 8388607.5;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Float64) (in[info.inOffset[j]].asInt());
+          out[info.outOffset[j]] += 0.5;
+          out[info.outOffset[j]] *= scale;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT32) {
+      Int32 *in = (Int32 *)inBuffer;
+      scale = 1.0 / 2147483647.5;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Float64) in[info.inOffset[j]];
+          out[info.outOffset[j]] += 0.5;
+          out[info.outOffset[j]] *= scale;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_FLOAT32) {
+      Float32 *in = (Float32 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Float64) in[info.inOffset[j]];
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_FLOAT64) {
+      // Channel compensation and/or (de)interleaving only.
+      Float64 *in = (Float64 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = in[info.inOffset[j]];
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+  }
+  else if (info.outFormat == RTAUDIO_FLOAT32) {
+    Float32 scale;
+    Float32 *out = (Float32 *)outBuffer;
+
+    if (info.inFormat == RTAUDIO_SINT8) {
+      signed char *in = (signed char *)inBuffer;
+      scale = (Float32) ( 1.0 / 127.5 );
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Float32) in[info.inOffset[j]];
+          out[info.outOffset[j]] += 0.5;
+          out[info.outOffset[j]] *= scale;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT16) {
+      Int16 *in = (Int16 *)inBuffer;
+      scale = (Float32) ( 1.0 / 32767.5 );
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Float32) in[info.inOffset[j]];
+          out[info.outOffset[j]] += 0.5;
+          out[info.outOffset[j]] *= scale;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT24) {
+      Int24 *in = (Int24 *)inBuffer;
+      scale = (Float32) ( 1.0 / 8388607.5 );
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Float32) (in[info.inOffset[j]].asInt());
+          out[info.outOffset[j]] += 0.5;
+          out[info.outOffset[j]] *= scale;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT32) {
+      Int32 *in = (Int32 *)inBuffer;
+      scale = (Float32) ( 1.0 / 2147483647.5 );
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Float32) in[info.inOffset[j]];
+          out[info.outOffset[j]] += 0.5;
+          out[info.outOffset[j]] *= scale;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_FLOAT32) {
+      // Channel compensation and/or (de)interleaving only.
+      Float32 *in = (Float32 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = in[info.inOffset[j]];
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_FLOAT64) {
+      Float64 *in = (Float64 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Float32) in[info.inOffset[j]];
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+  }
+  else if (info.outFormat == RTAUDIO_SINT32) {
+    Int32 *out = (Int32 *)outBuffer;
+    if (info.inFormat == RTAUDIO_SINT8) {
+      signed char *in = (signed char *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int32) in[info.inOffset[j]];
+          out[info.outOffset[j]] <<= 24;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT16) {
+      Int16 *in = (Int16 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int32) in[info.inOffset[j]];
+          out[info.outOffset[j]] <<= 16;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT24) {
+      Int24 *in = (Int24 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int32) in[info.inOffset[j]].asInt();
+          out[info.outOffset[j]] <<= 8;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT32) {
+      // Channel compensation and/or (de)interleaving only.
+      Int32 *in = (Int32 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = in[info.inOffset[j]];
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_FLOAT32) {
+      Float32 *in = (Float32 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] * 2147483647.5 - 0.5);
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_FLOAT64) {
+      Float64 *in = (Float64 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] * 2147483647.5 - 0.5);
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+  }
+  else if (info.outFormat == RTAUDIO_SINT24) {
+    Int24 *out = (Int24 *)outBuffer;
+    if (info.inFormat == RTAUDIO_SINT8) {
+      signed char *in = (signed char *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] << 16);
+          //out[info.outOffset[j]] <<= 16;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT16) {
+      Int16 *in = (Int16 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] << 8);
+          //out[info.outOffset[j]] <<= 8;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT24) {
+      // Channel compensation and/or (de)interleaving only.
+      Int24 *in = (Int24 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = in[info.inOffset[j]];
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT32) {
+      Int32 *in = (Int32 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] >> 8);
+          //out[info.outOffset[j]] >>= 8;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_FLOAT32) {
+      Float32 *in = (Float32 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] * 8388607.5 - 0.5);
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_FLOAT64) {
+      Float64 *in = (Float64 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] * 8388607.5 - 0.5);
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+  }
+  else if (info.outFormat == RTAUDIO_SINT16) {
+    Int16 *out = (Int16 *)outBuffer;
+    if (info.inFormat == RTAUDIO_SINT8) {
+      signed char *in = (signed char *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int16) in[info.inOffset[j]];
+          out[info.outOffset[j]] <<= 8;
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT16) {
+      // Channel compensation and/or (de)interleaving only.
+      Int16 *in = (Int16 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = in[info.inOffset[j]];
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT24) {
+      Int24 *in = (Int24 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int16) (in[info.inOffset[j]].asInt() >> 8);
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT32) {
+      Int32 *in = (Int32 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int16) ((in[info.inOffset[j]] >> 16) & 0x0000ffff);
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_FLOAT32) {
+      Float32 *in = (Float32 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int16) (in[info.inOffset[j]] * 32767.5 - 0.5);
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_FLOAT64) {
+      Float64 *in = (Float64 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (Int16) (in[info.inOffset[j]] * 32767.5 - 0.5);
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+  }
+  else if (info.outFormat == RTAUDIO_SINT8) {
+    signed char *out = (signed char *)outBuffer;
+    if (info.inFormat == RTAUDIO_SINT8) {
+      // Channel compensation and/or (de)interleaving only.
+      signed char *in = (signed char *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = in[info.inOffset[j]];
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    if (info.inFormat == RTAUDIO_SINT16) {
+      Int16 *in = (Int16 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (signed char) ((in[info.inOffset[j]] >> 8) & 0x00ff);
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT24) {
+      Int24 *in = (Int24 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (signed char) (in[info.inOffset[j]].asInt() >> 16);
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_SINT32) {
+      Int32 *in = (Int32 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (signed char) ((in[info.inOffset[j]] >> 24) & 0x000000ff);
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_FLOAT32) {
+      Float32 *in = (Float32 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (signed char) (in[info.inOffset[j]] * 127.5 - 0.5);
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+    else if (info.inFormat == RTAUDIO_FLOAT64) {
+      Float64 *in = (Float64 *)inBuffer;
+      for (unsigned int i=0; i<stream_.bufferSize; i++) {
+        for (j=0; j<info.channels; j++) {
+          out[info.outOffset[j]] = (signed char) (in[info.inOffset[j]] * 127.5 - 0.5);
+        }
+        in += info.inJump;
+        out += info.outJump;
+      }
+    }
+  }
+}
+
+//static inline uint16_t bswap_16(uint16_t x) { return (x>>8) | (x<<8); }
+//static inline uint32_t bswap_32(uint32_t x) { return (bswap_16(x&0xffff)<<16) | (bswap_16(x>>16)); }
+//static inline uint64_t bswap_64(uint64_t x) { return (((unsigned long long)bswap_32(x&0xffffffffull))<<32) | (bswap_32(x>>32)); }
+
+void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format )
+{
+  register char val;
+  register char *ptr;
+
+  ptr = buffer;
+  if ( format == RTAUDIO_SINT16 ) {
+    for ( unsigned int i=0; i<samples; i++ ) {
+      // Swap 1st and 2nd bytes.
+      val = *(ptr);
+      *(ptr) = *(ptr+1);
+      *(ptr+1) = val;
+
+      // Increment 2 bytes.
+      ptr += 2;
+    }
+  }
+  else if ( format == RTAUDIO_SINT32 ||
+            format == RTAUDIO_FLOAT32 ) {
+    for ( unsigned int i=0; i<samples; i++ ) {
+      // Swap 1st and 4th bytes.
+      val = *(ptr);
+      *(ptr) = *(ptr+3);
+      *(ptr+3) = val;
+
+      // Swap 2nd and 3rd bytes.
+      ptr += 1;
+      val = *(ptr);
+      *(ptr) = *(ptr+1);
+      *(ptr+1) = val;
+
+      // Increment 3 more bytes.
+      ptr += 3;
+    }
+  }
+  else if ( format == RTAUDIO_SINT24 ) {
+    for ( unsigned int i=0; i<samples; i++ ) {
+      // Swap 1st and 3rd bytes.
+      val = *(ptr);
+      *(ptr) = *(ptr+2);
+      *(ptr+2) = val;
+
+      // Increment 2 more bytes.
+      ptr += 2;
+    }
+  }
+  else if ( format == RTAUDIO_FLOAT64 ) {
+    for ( unsigned int i=0; i<samples; i++ ) {
+      // Swap 1st and 8th bytes
+      val = *(ptr);
+      *(ptr) = *(ptr+7);
+      *(ptr+7) = val;
+
+      // Swap 2nd and 7th bytes
+      ptr += 1;
+      val = *(ptr);
+      *(ptr) = *(ptr+5);
+      *(ptr+5) = val;
+
+      // Swap 3rd and 6th bytes
+      ptr += 1;
+      val = *(ptr);
+      *(ptr) = *(ptr+3);
+      *(ptr+3) = val;
+
+      // Swap 4th and 5th bytes
+      ptr += 1;
+      val = *(ptr);
+      *(ptr) = *(ptr+1);
+      *(ptr+1) = val;
+
+      // Increment 5 more bytes.
+      ptr += 5;
+    }
+  }
+}
+
+  // Indentation settings for Vim and Emacs
+  //
+  // Local Variables:
+  // c-basic-offset: 2
+  // indent-tabs-mode: nil
+  // End:
+  //
+  // vim: et sts=2 sw=2
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/src/RtWvOut.cpp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,214 @@
+/***************************************************/
+/*! \class RtWvOut
+    \brief STK realtime audio (blocking) output class.
+
+    This class provides a simplified interface to RtAudio for realtime
+    audio output.  It is a subclass of WvOut.  This class makes use of
+    RtAudio's callback functionality by creating a large ring-buffer
+    into which data is written.  This class should not be used when
+    low-latency is desired.
+
+    RtWvOut supports multi-channel data in interleaved format.  It is
+    important to distinguish the tick() method that outputs a single
+    sample to all channels in a sample frame from the overloaded one
+    that takes a reference to an StkFrames object for multi-channel
+    and/or multi-frame data.
+
+    by Perry R. Cook and Gary P. Scavone, 1995--2014.
+*/
+/***************************************************/
+#pragma once
+
+#include "../include/RtWvOut.h"
+#include <cstring>
+
+namespace stk {
+
+// Streaming status states.
+enum { RUNNING, EMPTYING, FINISHED };
+
+// This function is automatically called by RtAudio to get audio data for output.
+int write( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
+           double streamTime, RtAudioStreamStatus status, void *dataPointer )
+{
+  return ( (RtWvOut *) dataPointer )->readBuffer( outputBuffer, nBufferFrames );
+}
+
+// This function does not block.  If the user does not write output
+// data to the buffer fast enough, previous data will be re-output
+// (data underrun).
+int RtWvOut :: readBuffer( void *buffer, unsigned int frameCount )
+{
+  unsigned int nSamples, nChannels = data_.channels();
+  unsigned int nFrames = frameCount;
+  StkFloat *input = (StkFloat *) &data_[ readIndex_ * nChannels ];
+  StkFloat *output = (StkFloat *) buffer;
+  long counter;
+
+  while ( nFrames > 0 ) {
+
+    // I'm assuming that both the RtAudio and StkFrames buffers
+    // contain interleaved data.
+    counter = nFrames;
+
+    // Pre-increment read pointer and check bounds.
+    readIndex_ += nFrames;
+    if ( readIndex_ >= data_.frames() ) {
+      counter -= readIndex_ - data_.frames();
+      readIndex_ = 0;
+    }
+
+    // Copy data from the StkFrames container.
+    if ( status_ == EMPTYING && framesFilled_ <= counter ) {
+      nSamples = framesFilled_ * nChannels;
+      unsigned int i;
+      for ( i=0; i<nSamples; i++ ) *output++ = *input++;
+      nSamples = (counter - framesFilled_) * nChannels;
+      for ( i=0; i<nSamples; i++ ) *output++ = 0.0;
+      status_ = FINISHED;
+      return 1;
+    }
+    else {
+      nSamples = counter * nChannels;
+      for ( unsigned int i=0; i<nSamples; i++ )
+        *output++ = *input++;
+    }
+
+    nFrames -= counter;
+  }
+
+  mutex_.lock();
+  framesFilled_ -= frameCount;
+  mutex_.unlock();
+  if ( framesFilled_ < 0 ) {
+    framesFilled_ = 0;
+    //    writeIndex_ = readIndex_;
+    oStream_ << "RtWvOut: audio buffer underrun!";
+    handleError( StkError::WARNING );
+  }
+
+  return 0;
+}
+
+
+RtWvOut :: RtWvOut( unsigned int nChannels, StkFloat sampleRate, int device, int bufferFrames, int nBuffers )
+  : stopped_( true ), readIndex_( 0 ), writeIndex_( 0 ), framesFilled_( 0 ), status_(0)
+{
+  // We'll let RtAudio deal with channel and sample rate limitations.
+  RtAudio::StreamParameters parameters;
+  if ( device == 0 )
+    parameters.deviceId = dac_.getDefaultOutputDevice();
+  else
+    parameters.deviceId = device - 1;
+  parameters.nChannels = nChannels;
+  unsigned int size = bufferFrames;
+  RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
+
+  // Open a stream and set the callback function.
+  try {
+    dac_.openStream( &parameters, NULL, format, (unsigned int)Stk::sampleRate(), &size, &write, (void *)this );
+  }
+  catch ( RtAudioError &error ) {
+    handleError( error.what(), StkError::AUDIO_SYSTEM );
+  }
+
+  data_.resize( size * nBuffers, nChannels );
+
+  // Start writing half-way into buffer.
+  writeIndex_ = (unsigned int ) (data_.frames() / 2.0);
+  framesFilled_ = writeIndex_;
+}
+
+RtWvOut :: ~RtWvOut( void )
+{
+  // Change status flag to signal callback to clear the buffer and close.
+  status_ = EMPTYING;
+  while ( status_ != FINISHED || dac_.isStreamRunning() == true ) Stk::sleep( 100 );
+  dac_.closeStream();
+}
+
+void RtWvOut :: start( void )
+{
+  if ( stopped_ ) {
+    dac_.startStream();
+    stopped_ = false;
+  }
+}
+
+void RtWvOut :: stop( void )
+{
+  if ( !stopped_ ) {
+    dac_.stopStream();
+    stopped_ = true;
+  }
+}
+
+void RtWvOut :: tick( const StkFloat sample )
+{
+  if ( stopped_ ) this->start();
+
+  // Block until we have room for at least one frame of output data.
+  while ( framesFilled_ == (long) data_.frames() ) Stk::sleep( 1 );
+
+  unsigned int nChannels = data_.channels();
+  StkFloat input = sample;
+  clipTest( input );
+  unsigned long index = writeIndex_ * nChannels;
+  for ( unsigned int j=0; j<nChannels; j++ )
+    data_[index++] = input;
+
+  mutex_.lock();
+  framesFilled_++;
+  mutex_.unlock();
+  frameCounter_++;
+  writeIndex_++;
+  if ( writeIndex_ == data_.frames() )
+    writeIndex_ = 0;
+}
+
+void RtWvOut :: tick( const StkFrames& frames )
+{
+#if defined(_STK_DEBUG_)
+  if ( data_.channels() != frames.channels() ) {
+    oStream_ << "RtWvOut::tick(): incompatible channel value in StkFrames argument!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  if ( stopped_ ) this->start();
+
+  // See how much space we have and fill as much as we can ... if we
+  // still have samples left in the frames object, then wait and
+  // repeat.
+  unsigned int framesEmpty, nFrames, bytes, framesWritten = 0;
+  unsigned int nChannels = data_.channels();
+  while ( framesWritten < frames.frames() ) {
+
+    // Block until we have some room for output data.
+    while ( framesFilled_ == (long) data_.frames() ) Stk::sleep( 1 );
+    framesEmpty = data_.frames() - framesFilled_;
+
+    // Copy data in one chunk up to the end of the data buffer.
+    nFrames = framesEmpty;
+    if ( writeIndex_ + nFrames > data_.frames() )
+      nFrames = data_.frames() - writeIndex_;
+    if ( nFrames > frames.frames() - framesWritten )
+      nFrames = frames.frames() - framesWritten;
+    bytes = nFrames * nChannels * sizeof( StkFloat );
+    StkFloat *samples = &data_[writeIndex_ * nChannels];
+    StkFrames *ins = (StkFrames *) &frames;
+    memcpy( samples, &(*ins)[framesWritten * nChannels], bytes );
+    for ( unsigned int i=0; i<nFrames * nChannels; i++ ) clipTest( *samples++ );
+
+    writeIndex_ += nFrames;
+    if ( writeIndex_ == data_.frames() ) writeIndex_ = 0;
+
+    framesWritten += nFrames;
+    mutex_.lock();
+    framesFilled_ += nFrames;
+    mutex_.unlock();
+    frameCounter_ += nFrames;
+  }
+}
+
+} // stk namespace
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/src/SineWave.cpp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,78 @@
+/***************************************************/
+/*! \class SineWave
+    \brief STK sinusoid oscillator class.
+
+    This class computes and saves a static sine "table" that can be
+    shared by multiple instances.  It has an interface similar to the
+    WaveLoop class but inherits from the Generator class.  Output
+    values are computed using linear interpolation.
+
+    The "table" length, set in SineWave.h, is 2048 samples by default.
+
+    by Perry R. Cook and Gary P. Scavone, 1995--2014.
+*/
+/***************************************************/
+
+#include "../include/SineWave.h"
+#include <cmath>
+
+namespace stk {
+
+StkFrames SineWave :: table_;
+
+SineWave :: SineWave( void )
+  : time_(0.0), rate_(1.0), phaseOffset_(0.0)
+{
+  if ( table_.empty() ) {
+    table_.resize( TABLE_SIZE + 1, 1 );
+    StkFloat temp = 1.0 / TABLE_SIZE;
+    for ( unsigned long i=0; i<=TABLE_SIZE; i++ )
+      table_[i] = sin( TWO_PI * i * temp );
+  }
+
+  Stk::addSampleRateAlert( this );
+}
+
+SineWave :: ~SineWave()
+{
+  Stk::removeSampleRateAlert( this );
+}
+
+void SineWave :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  if ( !ignoreSampleRateChange_ )
+    this->setRate( oldRate * rate_ / newRate );
+}
+
+void SineWave :: reset( void )
+{
+  time_ = 0.0;
+  lastFrame_[0] = 0;
+}
+
+void SineWave :: setFrequency( StkFloat frequency )
+{
+  // This is a looping frequency.
+  this->setRate( TABLE_SIZE * frequency / Stk::sampleRate() );
+}
+
+void SineWave :: addTime( StkFloat time )
+{
+  // Add an absolute time in samples.
+  time_ += time;
+}
+
+void SineWave :: addPhase( StkFloat phase )
+{
+  // Add a time in cycles (one cycle = TABLE_SIZE).
+  time_ += TABLE_SIZE * phase;
+}
+
+void SineWave :: addPhaseOffset( StkFloat phaseOffset )
+{
+  // Add a phase offset relative to any previous offset value.
+  time_ += ( phaseOffset - phaseOffset_ ) * TABLE_SIZE;
+  phaseOffset_ = phaseOffset;
+}
+
+} // stk namespace
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/src/Stk.cpp	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,340 @@
+/***************************************************/
+/*! \class Stk
+    \brief STK base class
+
+    Nearly all STK classes inherit from this class.
+    The global sample rate can be queried and
+    modified via Stk.  In addition, this class
+    provides error handling and byte-swapping
+    functions.
+
+    The Synthesis ToolKit in C++ (STK) is a set of open source audio
+    signal processing and algorithmic synthesis classes written in the
+    C++ programming language. STK was designed to facilitate rapid
+    development of music synthesis and audio processing software, with
+    an emphasis on cross-platform functionality, realtime control,
+    ease of use, and educational example code.  STK currently runs
+    with realtime support (audio and MIDI) on Linux, Macintosh OS X,
+    and Windows computer platforms. Generic, non-realtime support has
+    been tested under NeXTStep, Sun, and other platforms and should
+    work with any standard C++ compiler.
+
+    STK WWW site: http://ccrma.stanford.edu/software/stk/
+
+    The Synthesis ToolKit in C++ (STK)
+    Copyright (c) 1995--2014 Perry R. Cook and Gary P. Scavone
+
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation files
+    (the "Software"), to deal in the Software without restriction,
+    including without limitation the rights to use, copy, modify, merge,
+    publish, distribute, sublicense, and/or sell copies of the Software,
+    and to permit persons to whom the Software is furnished to do so,
+    subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    Any person wishing to distribute modifications to the Software is
+    asked to send the modifications to the original developer so that
+    they can be incorporated into the canonical version.  This is,
+    however, not a binding provision of this license.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/***************************************************/
+
+#include "../include/Stk.h"
+#include <stdlib.h>
+
+namespace stk {
+
+StkFloat Stk :: srate_ = (StkFloat) SRATE;
+std::string Stk :: rawwavepath_ = RAWWAVE_PATH;
+const Stk::StkFormat Stk :: STK_SINT8   = 0x1;
+const Stk::StkFormat Stk :: STK_SINT16  = 0x2;
+const Stk::StkFormat Stk :: STK_SINT24  = 0x4;
+const Stk::StkFormat Stk :: STK_SINT32  = 0x8;
+const Stk::StkFormat Stk :: STK_FLOAT32 = 0x10;
+const Stk::StkFormat Stk :: STK_FLOAT64 = 0x20;
+bool Stk :: showWarnings_ = true;
+bool Stk :: printErrors_ = true;
+std::vector<Stk *> Stk :: alertList_;
+std::ostringstream Stk :: oStream_;
+
+Stk :: Stk( void )
+  : ignoreSampleRateChange_(false)
+{
+}
+
+Stk :: ~Stk( void )
+{
+}
+
+void Stk :: setSampleRate( StkFloat rate )
+{
+  if ( rate > 0.0 && rate != srate_ ) {
+    StkFloat oldRate = srate_;
+    srate_ = rate;
+
+    for ( unsigned int i=0; i<alertList_.size(); i++ )
+      alertList_[i]->sampleRateChanged( srate_, oldRate );
+  }
+}
+
+void Stk :: sampleRateChanged( StkFloat /*newRate*/, StkFloat /*oldRate*/ )
+{
+  // This function should be reimplemented in classes that need to
+  // make internal variable adjustments in response to a global sample
+  // rate change.
+}
+
+void Stk :: addSampleRateAlert( Stk *ptr )
+{
+  for ( unsigned int i=0; i<alertList_.size(); i++ )
+    if ( alertList_[i] == ptr ) return;
+
+  alertList_.push_back( ptr );
+}
+
+void Stk :: removeSampleRateAlert( Stk *ptr )
+{
+  for ( unsigned int i=0; i<alertList_.size(); i++ ) {
+    if ( alertList_[i] == ptr ) {
+      alertList_.erase( alertList_.begin() + i );
+      return;
+    }
+  }
+}
+
+void Stk :: setRawwavePath( std::string path )
+{
+  if ( !path.empty() )
+    rawwavepath_ = path;
+
+  // Make sure the path includes a "/"
+  if ( rawwavepath_[rawwavepath_.length()-1] != '/' )
+    rawwavepath_ += "/";
+}
+
+void Stk :: swap16(unsigned char *ptr)
+{
+  unsigned char val;
+
+  // Swap 1st and 2nd bytes
+  val = *(ptr);
+  *(ptr) = *(ptr+1);
+  *(ptr+1) = val;
+}
+
+void Stk :: swap32(unsigned char *ptr)
+{
+  unsigned char val;
+
+  // Swap 1st and 4th bytes
+  val = *(ptr);
+  *(ptr) = *(ptr+3);
+  *(ptr+3) = val;
+
+  //Swap 2nd and 3rd bytes
+  ptr += 1;
+  val = *(ptr);
+  *(ptr) = *(ptr+1);
+  *(ptr+1) = val;
+}
+
+void Stk :: swap64(unsigned char *ptr)
+{
+  unsigned char val;
+
+  // Swap 1st and 8th bytes
+  val = *(ptr);
+  *(ptr) = *(ptr+7);
+  *(ptr+7) = val;
+
+  // Swap 2nd and 7th bytes
+  ptr += 1;
+  val = *(ptr);
+  *(ptr) = *(ptr+5);
+  *(ptr+5) = val;
+
+  // Swap 3rd and 6th bytes
+  ptr += 1;
+  val = *(ptr);
+  *(ptr) = *(ptr+3);
+  *(ptr+3) = val;
+
+  // Swap 4th and 5th bytes
+  ptr += 1;
+  val = *(ptr);
+  *(ptr) = *(ptr+1);
+  *(ptr+1) = val;
+}
+
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+  #include <unistd.h>
+#elif defined(__OS_WINDOWS__)
+  #include <windows.h>
+#endif
+
+void Stk :: sleep(unsigned long milliseconds)
+{
+#if defined(__OS_WINDOWS__)
+  Sleep((DWORD) milliseconds);
+#elif (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+  usleep( (unsigned long) (milliseconds * 1000.0) );
+#endif
+}
+
+void Stk :: handleError( StkError::Type type ) const
+{
+  handleError( oStream_.str(), type );
+  oStream_.str( std::string() ); // reset the ostringstream buffer
+}
+
+void Stk :: handleError( const char *message, StkError::Type type )
+{
+  std::string msg( message );
+  handleError( msg, type );
+}
+
+void Stk :: handleError( std::string message, StkError::Type type )
+{
+  if ( type == StkError::WARNING || type == StkError::STATUS ) {
+    if ( !showWarnings_ ) return;
+    std::cerr << '\n' << message << '\n' << std::endl;
+  }
+  else if (type == StkError::DEBUG_PRINT) {
+#if defined(_STK_DEBUG_)
+    std::cerr << '\n' << message << '\n' << std::endl;
+#endif
+  }
+  else {
+    if ( printErrors_ ) {
+      // Print error message before throwing.
+      std::cerr << '\n' << message << '\n' << std::endl;
+    }
+    throw StkError(message, type);
+  }
+}
+
+//
+// StkFrames definitions
+//
+
+StkFrames :: StkFrames( unsigned int nFrames, unsigned int nChannels )
+  : data_( 0 ), nFrames_( nFrames ), nChannels_( nChannels )
+{
+  size_ = nFrames_ * nChannels_;
+  bufferSize_ = size_;
+
+  if ( size_ > 0 ) {
+    data_ = (StkFloat *) calloc( size_, sizeof( StkFloat ) );
+#if defined(_STK_DEBUG_)
+    if ( data_ == NULL ) {
+      std::string error = "StkFrames: memory allocation error in constructor!";
+      Stk::handleError( error, StkError::MEMORY_ALLOCATION );
+    }
+#endif
+  }
+
+  dataRate_ = Stk::sampleRate();
+}
+
+StkFrames :: StkFrames( const StkFloat& value, unsigned int nFrames, unsigned int nChannels )
+  : data_( 0 ), nFrames_( nFrames ), nChannels_( nChannels )
+{
+  size_ = nFrames_ * nChannels_;
+  bufferSize_ = size_;
+  if ( size_ > 0 ) {
+    data_ = (StkFloat *) malloc( size_ * sizeof( StkFloat ) );
+#if defined(_STK_DEBUG_)
+    if ( data_ == NULL ) {
+      std::string error = "StkFrames: memory allocation error in constructor!";
+      Stk::handleError( error, StkError::MEMORY_ALLOCATION );
+    }
+#endif
+    for ( long i=0; i<(long)size_; i++ ) data_[i] = value;
+  }
+
+  dataRate_ = Stk::sampleRate();
+}
+
+StkFrames :: ~StkFrames()
+{
+  if ( data_ ) free( data_ );
+}
+
+StkFrames :: StkFrames( const StkFrames& f )
+  : data_(0), size_(0), bufferSize_(0)
+{
+  resize( f.frames(), f.channels() );
+  dataRate_ = Stk::sampleRate();
+  for ( unsigned int i=0; i<size_; i++ ) data_[i] = f[i];
+}
+
+StkFrames& StkFrames :: operator= ( const StkFrames& f )
+{
+  data_ = 0;
+  size_ = 0;
+  bufferSize_ = 0;
+  resize( f.frames(), f.channels() );
+  dataRate_ = Stk::sampleRate();
+  for ( unsigned int i=0; i<size_; i++ ) data_[i] = f[i];
+  return *this;
+}
+
+void StkFrames :: resize( size_t nFrames, unsigned int nChannels )
+{
+  nFrames_ = nFrames;
+  nChannels_ = nChannels;
+
+  size_ = nFrames_ * nChannels_;
+  if ( size_ > bufferSize_ ) {
+    if ( data_ ) free( data_ );
+    data_ = (StkFloat *) malloc( size_ * sizeof( StkFloat ) );
+#if defined(_STK_DEBUG_)
+    if ( data_ == NULL ) {
+      std::string error = "StkFrames::resize: memory allocation error!";
+      Stk::handleError( error, StkError::MEMORY_ALLOCATION );
+    }
+#endif
+    bufferSize_ = size_;
+  }
+}
+
+void StkFrames :: resize( size_t nFrames, unsigned int nChannels, StkFloat value )
+{
+  this->resize( nFrames, nChannels );
+
+  for ( size_t i=0; i<size_; i++ ) data_[i] = value;
+}
+
+StkFloat StkFrames :: interpolate( StkFloat frame, unsigned int channel ) const
+{
+#if defined(_STK_DEBUG_)
+  if ( frame < 0.0 || frame > (StkFloat) ( nFrames_ - 1 ) || channel >= nChannels_ ) {
+    std::ostringstream error;
+    error << "StkFrames::interpolate: invalid frame (" << frame << ") or channel (" << channel << ") value!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  size_t iIndex = ( size_t ) frame;                    // integer part of index
+  StkFloat output, alpha = frame - (StkFloat) iIndex;  // fractional part of index
+
+  iIndex = iIndex * nChannels_ + channel;
+  output = data_[ iIndex ];
+  if ( alpha > 0.0 )
+    output += ( alpha * ( data_[ iIndex + nChannels_ ] - output ) );
+
+  return output;
+}
+
+} // stk namespace
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stk/stk-license.txt	Sat Jun 13 15:08:10 2015 +0100
@@ -0,0 +1,39 @@
+The Synthesis ToolKit in C++ (STK) is a set of open source audio
+signal processing and algorithmic synthesis classes written in the
+C++ programming language. STK was designed to facilitate rapid
+development of music synthesis and audio processing software, with
+an emphasis on cross-platform functionality, realtime control,
+ease of use, and educational example code.  STK currently runs
+with realtime support (audio and MIDI) on Linux, Macintosh OS X,
+and Windows computer platforms. Generic, non-realtime support has
+been tested under NeXTStep, Sun, and other platforms and should
+work with any standard C++ compiler.
+
+STK WWW site: http://ccrma.stanford.edu/software/stk/
+
+The Synthesis ToolKit in C++ (STK)
+Copyright (c) 1995--2014 Perry R. Cook and Gary P. Scavone
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+Any person wishing to distribute modifications to the Software is
+asked to send the modifications to the original developer so that they
+can be incorporated into the canonical version.  This is, however, not
+a binding provision of this license.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.