From: dttsp <dttsp>
Date: Sun, 12 Jun 2005 13:49:26 +0000 (+0000)
Subject: Upgraded windows alternatives
X-Git-Url: https://git.rkrishnan.org/components/%22news.html/frontends/%5B/%5D%20/uri/%3C?a=commitdiff_plain;h=e096691e78a12807cd4a36f0add48d0f7a2eab29;p=dttsp.git

Upgraded windows alternatives
---

diff --git a/jDttSP/win/DttSP.def b/jDttSP/win/DttSP.def
new file mode 100644
index 0000000..1450e73
--- /dev/null
+++ b/jDttSP/win/DttSP.def
@@ -0,0 +1,5 @@
+LIBRARY    DttSP
+EXPORTS
+   audio_callback	    @1
+   setup_sdr			@2
+   destroy_sdr			@3
diff --git a/jDttSP/win/DttSP.sln b/jDttSP/win/DttSP.sln
new file mode 100644
index 0000000..97d2d92
--- /dev/null
+++ b/jDttSP/win/DttSP.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DttSP", "DttSP.vcproj", "{E8E40DF8-8A3B-422D-B7A1-44BB036F4994}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfiguration) = preSolution
+		Debug = Debug
+		Release = Release
+	EndGlobalSection
+	GlobalSection(ProjectConfiguration) = postSolution
+		{E8E40DF8-8A3B-422D-B7A1-44BB036F4994}.Debug.ActiveCfg = Debug|Win32
+		{E8E40DF8-8A3B-422D-B7A1-44BB036F4994}.Debug.Build.0 = Debug|Win32
+		{E8E40DF8-8A3B-422D-B7A1-44BB036F4994}.Release.ActiveCfg = Release|Win32
+		{E8E40DF8-8A3B-422D-B7A1-44BB036F4994}.Release.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+	EndGlobalSection
+	GlobalSection(ExtensibilityAddIns) = postSolution
+	EndGlobalSection
+EndGlobal
diff --git a/jDttSP/win/DttSP.vcproj b/jDttSP/win/DttSP.vcproj
new file mode 100644
index 0000000..9f7e285
--- /dev/null
+++ b/jDttSP/win/DttSP.vcproj
@@ -0,0 +1,346 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="DttSP"
+	ProjectGUID="{E8E40DF8-8A3B-422D-B7A1-44BB036F4994}"
+	RootNamespace="DttSP"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../temp/Debug/DttSP"
+			IntermediateDirectory="../../temp/Debug/DttSP"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/D_WIN32_WINNT&gt;=0x0400"
+				Optimization="0"
+				AdditionalIncludeDirectories="./;../FFTW/fftw;&quot;../pthread&quot;"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;DttSP_EXPORTS;__CLEANUP_C"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)/"
+				BrowseInformation="1"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="FALSE"
+				DebugInformationFormat="3"
+				CompileAs="1"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="../../bin/Debug/DttSP.dll"
+				LinkIncremental="2"
+				ModuleDefinitionFile="./DttSP.def"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/DttSP.pdb"
+				SubSystem="2"
+				ImportLibrary="$(OutDir)/DttSP.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				ExcludedFromBuild="TRUE"/>
+			<Tool
+				Name="VCPreBuildEventTool"
+				ExcludedFromBuild="TRUE"/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				ExcludedFromBuild="TRUE"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../temp/Release/DttSP"
+			IntermediateDirectory="../../temp/Release/DttSP"
+			ConfigurationType="2"
+			CharacterSet="0">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/D_WIN32_WINNT&gt;=0x0400"
+				InlineFunctionExpansion="2"
+				EnableIntrinsicFunctions="TRUE"
+				ImproveFloatingPointConsistency="TRUE"
+				FavorSizeOrSpeed="1"
+				OptimizeForProcessor="0"
+				OptimizeForWindowsApplication="TRUE"
+				AdditionalIncludeDirectories="&quot;.&quot;;&quot;..\FFTW\fftw&quot;;&quot;..\pthread&quot;"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;DttSP_EXPORTS"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)/"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="FALSE"
+				DebugInformationFormat="0"
+				CompileAs="1"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="../../bin/Release/DttSP.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ModuleDefinitionFile="./DttSP.def"
+				GenerateDebugInformation="FALSE"
+				GenerateMapFile="FALSE"
+				MapFileName="$(OutDir)/$(ProjectName).map"
+				MapExports="FALSE"
+				SubSystem="2"
+				OptimizeReferences="0"
+				EnableCOMDATFolding="0"
+				OptimizeForWindows98="1"
+				ImportLibrary="$(IntDir)/DttSP.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				ExcludedFromBuild="TRUE"/>
+			<Tool
+				Name="VCPreBuildEventTool"
+				ExcludedFromBuild="TRUE"/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				ExcludedFromBuild="TRUE"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath=".\am_demod.c">
+			</File>
+			<File
+				RelativePath=".\banal.c">
+			</File>
+			<File
+				RelativePath=".\bufvec.c">
+			</File>
+			<File
+				RelativePath=".\chan.c">
+			</File>
+			<File
+				RelativePath=".\chap.c">
+			</File>
+			<File
+				RelativePath=".\correctIQ.c">
+			</File>
+			<File
+				RelativePath=".\crc16.c">
+			</File>
+			<File
+				RelativePath=".\cxops.c">
+			</File>
+			<File
+				RelativePath=".\digitalagc.c">
+			</File>
+			<File
+				RelativePath=".\fastrig.c">
+			</File>
+			<File
+				RelativePath=".\filter.c">
+			</File>
+			<File
+				RelativePath=".\fm_demod.c">
+			</File>
+			<File
+				RelativePath=".\lmadf.c">
+			</File>
+			<File
+				RelativePath=".\main.c">
+			</File>
+			<File
+				RelativePath=".\meter.c">
+			</File>
+			<File
+				RelativePath=".\noiseblanker.c">
+			</File>
+			<File
+				RelativePath=".\oscillator.c">
+			</File>
+			<File
+				RelativePath=".\ovsv.c">
+			</File>
+			<File
+				RelativePath=".\power_spectrum.c">
+			</File>
+			<File
+				RelativePath=".\ringb.c">
+			</File>
+			<File
+				RelativePath=".\sdr.c">
+			</File>
+			<File
+				RelativePath=".\sdrexport.c">
+			</File>
+			<File
+				RelativePath=".\speechproc.c">
+			</File>
+			<File
+				RelativePath=".\splitfields.c">
+			</File>
+			<File
+				RelativePath=".\spottone.c">
+			</File>
+			<File
+				RelativePath=".\thunk.c">
+			</File>
+			<File
+				RelativePath=".\update.c">
+			</File>
+			<File
+				RelativePath=".\window.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+			<File
+				RelativePath=".\am_demod.h">
+			</File>
+			<File
+				RelativePath=".\banal.h">
+			</File>
+			<File
+				RelativePath=".\bufvec.h">
+			</File>
+			<File
+				RelativePath=".\chan.h">
+			</File>
+			<File
+				RelativePath=".\chap.h">
+			</File>
+			<File
+				RelativePath=".\common.h">
+			</File>
+			<File
+				RelativePath=".\complex.h">
+			</File>
+			<File
+				RelativePath=".\correctIQ.h">
+			</File>
+			<File
+				RelativePath=".\crc16.h">
+			</File>
+			<File
+				RelativePath=".\cxops.h">
+			</File>
+			<File
+				RelativePath=".\datatypes.h">
+			</File>
+			<File
+				RelativePath=".\digitalagc.h">
+			</File>
+			<File
+				RelativePath=".\fastrig.h">
+			</File>
+			<File
+				RelativePath="..\Fftw\fftw\fftw.h">
+			</File>
+			<File
+				RelativePath=".\filter.h">
+			</File>
+			<File
+				RelativePath=".\firdes.h">
+			</File>
+			<File
+				RelativePath=".\fm_demod.h">
+			</File>
+			<File
+				RelativePath=".\fromsys.h">
+			</File>
+			<File
+				RelativePath=".\lmadf.h">
+			</File>
+			<File
+				RelativePath=".\meter.h">
+			</File>
+			<File
+				RelativePath=".\noiseblanker.h">
+			</File>
+			<File
+				RelativePath=".\oscillator.h">
+			</File>
+			<File
+				RelativePath=".\ovsv.h">
+			</File>
+			<File
+				RelativePath=".\power_spectrum.h">
+			</File>
+			<File
+				RelativePath=".\ringb.h">
+			</File>
+			<File
+				RelativePath=".\sdrexport.h">
+			</File>
+			<File
+				RelativePath=".\speechproc.h">
+			</File>
+			<File
+				RelativePath=".\splitfields.h">
+			</File>
+			<File
+				RelativePath=".\spottone.h">
+			</File>
+			<File
+				RelativePath=".\statistics.h">
+			</File>
+			<File
+				RelativePath=".\thunk.h">
+			</File>
+			<File
+				RelativePath=".\update.h">
+			</File>
+			<File
+				RelativePath=".\valueswin.h">
+			</File>
+			<File
+				RelativePath=".\window.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/jDttSP/win/DttSPtmp.vcproj b/jDttSP/win/DttSPtmp.vcproj
new file mode 100644
index 0000000..34a6f00
--- /dev/null
+++ b/jDttSP/win/DttSPtmp.vcproj
@@ -0,0 +1,385 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="DttSP"
+	ProjectGUID="{E8E40DF8-8A3B-422D-B7A1-44BB036F4994}"
+	RootNamespace="DttSP"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../temp/Debug"
+			IntermediateDirectory="../../temp/Debug"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="./;"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;DttSP_EXPORTS"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)/"
+				BrowseInformation="1"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(IntDir)/FFTW2.lib"
+				OutputFile="../../bin/Debug/DttSP.dll"
+				LinkIncremental="1"
+				ModuleDefinitionFile="./DttSP.def"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/DttSP.pdb"
+				SubSystem="2"
+				ImportLibrary="$(OutDir)/DttSP.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				ExcludedFromBuild="TRUE"/>
+			<Tool
+				Name="VCPreBuildEventTool"
+				ExcludedFromBuild="TRUE"/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				ExcludedFromBuild="TRUE"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../temp/Release"
+			IntermediateDirectory="../../temp/Release"
+			ConfigurationType="2"
+			CharacterSet="0">
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="2"
+				EnableIntrinsicFunctions="TRUE"
+				ImproveFloatingPointConsistency="TRUE"
+				FavorSizeOrSpeed="1"
+				OptimizeForProcessor="0"
+				OptimizeForWindowsApplication="TRUE"
+				AdditionalIncludeDirectories="&quot;.&quot;;&quot;..\FFTW\fftw&quot;;."
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;DttSP_EXPORTS"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)/"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="FALSE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(IntDir)/FFTW2.lib"
+				OutputFile="../../bin/Release/DttSP.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ModuleDefinitionFile="./DttSP.def"
+				GenerateDebugInformation="FALSE"
+				GenerateMapFile="FALSE"
+				MapFileName="$(OutDir)/$(ProjectName).map"
+				MapExports="FALSE"
+				SubSystem="2"
+				OptimizeReferences="0"
+				EnableCOMDATFolding="0"
+				OptimizeForWindows98="1"
+				ImportLibrary="$(IntDir)/DttSP.lib"
+				TargetMachine="0"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				ExcludedFromBuild="TRUE"/>
+			<Tool
+				Name="VCPreBuildEventTool"
+				ExcludedFromBuild="TRUE"/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				ExcludedFromBuild="TRUE"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath=".\am_demod.c">
+			</File>
+			<File
+				RelativePath=".\banal.c">
+			</File>
+			<File
+				RelativePath=".\bufvec.c">
+			</File>
+			<File
+				RelativePath=".\chan.c">
+			</File>
+			<File
+				RelativePath=".\chap.c">
+			</File>
+			<File
+				RelativePath=".\correctIQ.c">
+			</File>
+			<File
+				RelativePath=".\crc16.c">
+			</File>
+			<File
+				RelativePath=".\cxops.c">
+			</File>
+			<File
+				RelativePath=".\digitalagc.c">
+			</File>
+			<File
+				RelativePath=".\DttSP.cpp">
+			</File>
+			<File
+				RelativePath=".\fastrig.c">
+			</File>
+			<File
+				RelativePath=".\filter.c">
+			</File>
+			<File
+				RelativePath=".\fm_demod.c">
+			</File>
+			<File
+				RelativePath=".\lmadf.c">
+			</File>
+			<File
+				RelativePath=".\main.c">
+			</File>
+			<File
+				RelativePath=".\noiseblanker.c">
+			</File>
+			<File
+				RelativePath=".\oscillator.c">
+			</File>
+			<File
+				RelativePath=".\ovsv.c">
+			</File>
+			<File
+				RelativePath=".\power_spectrum.c">
+			</File>
+			<File
+				RelativePath=".\ringb.c">
+			</File>
+			<File
+				RelativePath=".\sdr.c">
+			</File>
+			<File
+				RelativePath=".\sdrexport.c">
+			</File>
+			<File
+				RelativePath=".\speechproc.c">
+			</File>
+			<File
+				RelativePath=".\splitfields.c">
+			</File>
+			<File
+				RelativePath=".\spottone.c">
+			</File>
+			<File
+				RelativePath=".\stdafx.cpp">
+				<FileConfiguration
+					Name="Debug|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32">
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\thunk.c">
+			</File>
+			<File
+				RelativePath=".\update.c">
+			</File>
+			<File
+				RelativePath=".\window.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+			<File
+				RelativePath=".\am_demod.h">
+			</File>
+			<File
+				RelativePath=".\banal.h">
+			</File>
+			<File
+				RelativePath=".\bufvec.h">
+			</File>
+			<File
+				RelativePath=".\chan.h">
+			</File>
+			<File
+				RelativePath=".\chap.h">
+			</File>
+			<File
+				RelativePath=".\common.h">
+			</File>
+			<File
+				RelativePath=".\complex.h">
+			</File>
+			<File
+				RelativePath=".\correctIQ.h">
+			</File>
+			<File
+				RelativePath=".\crc16.h">
+			</File>
+			<File
+				RelativePath=".\cxops.h">
+			</File>
+			<File
+				RelativePath=".\datatypes.h">
+			</File>
+			<File
+				RelativePath=".\digitalagc.h">
+			</File>
+			<File
+				RelativePath=".\DttSP.h">
+			</File>
+			<File
+				RelativePath=".\fastrig.h">
+			</File>
+			<File
+				RelativePath=".\fftw.h">
+			</File>
+			<File
+				RelativePath=".\filter.h">
+			</File>
+			<File
+				RelativePath=".\firdes.h">
+			</File>
+			<File
+				RelativePath=".\fm_demod.h">
+			</File>
+			<File
+				RelativePath=".\fromsys.h">
+			</File>
+			<File
+				RelativePath=".\lmadf.h">
+			</File>
+			<File
+				RelativePath=".\noiseblanker.h">
+			</File>
+			<File
+				RelativePath=".\oscillator.h">
+			</File>
+			<File
+				RelativePath=".\ovsv.h">
+			</File>
+			<File
+				RelativePath=".\power_spectrum.h">
+			</File>
+			<File
+				RelativePath=".\ringb.h">
+			</File>
+			<File
+				RelativePath=".\sdrexport.h">
+				<FileConfiguration
+					Name="Debug|Win32">
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Moc&apos;ing sdrexport.h..."
+						CommandLine="$(QTDIR)\bin\moc.exe .\sdrexport.h -o tmp\moc\moc_sdrexport.cpp
+"
+						AdditionalDependencies="$(QTDIR)\bin\moc.exe"
+						Outputs="tmp\moc\moc_sdrexport.cpp"/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32">
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Moc&apos;ing sdrexport.h..."
+						CommandLine="$(QTDIR)\bin\moc.exe .\sdrexport.h -o tmp\moc\moc_sdrexport.cpp
+"
+						AdditionalDependencies="$(QTDIR)\bin\moc.exe"
+						Outputs="tmp\moc\moc_sdrexport.cpp"/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\speechproc.h">
+			</File>
+			<File
+				RelativePath=".\splitfields.h">
+			</File>
+			<File
+				RelativePath=".\spottone.h">
+			</File>
+			<File
+				RelativePath=".\statistics.h">
+			</File>
+			<File
+				RelativePath=".\stdafx.h">
+			</File>
+			<File
+				RelativePath=".\thunk.h">
+			</File>
+			<File
+				RelativePath=".\update.h">
+			</File>
+			<File
+				RelativePath=".\valueswin.h">
+			</File>
+			<File
+				RelativePath=".\window.h">
+			</File>
+			<File
+				RelativePath=".\wvlt.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/jDttSP/win/iosdr.h b/jDttSP/win/iosdr.h
new file mode 100644
index 0000000..3425566
--- /dev/null
+++ b/jDttSP/win/iosdr.h
@@ -0,0 +1 @@
+extern int write(int, void*,unsigned int);
diff --git a/jDttSP/win/keyb.c b/jDttSP/win/keyb.c
new file mode 100644
index 0000000..d01707e
--- /dev/null
+++ b/jDttSP/win/keyb.c
@@ -0,0 +1,558 @@
+/* keyb.c */
+/*
+This file is part of a program that implements a Software-Defined Radio.
+
+Copyright (C) 2004 by Frank Brickle, AB2KT and Bob McGwier, N4HY
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+The authors can be reached by email at
+
+ab2kt@arrl.net
+or
+rwmcgwier@comcast.net
+
+or by paper mail at
+
+The DTTS Microwave Society
+6 Kathleen Place
+Bridgewater, NJ 08807
+*/  
+
+#include <fromsys.h>
+#include <banal.h>
+#include <splitfields.h>
+#include <datatypes.h>
+#include <bufvec.h>
+#include <cxops.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <ringb.h>
+
+#define SAMP_RATE (48000)
+#define HUGE_PHASE (1256637061.43593)
+
+#define RING_SIZE (01 << 020)
+
+static pthread_t input, play;
+static sem_t ready, reader, writer;
+
+ringb_t *lring, *rring;
+int size;
+
+static BOOLEAN playing = FALSE;
+static double wpm = 18.0, freq = 750.0, gain = -6.0, ramp = 5.0;
+
+COMPLEX *zout = 0;
+
+// basic mapping, chars -> morse strings
+char *morse_table[128];
+
+// CW tone segments
+#define ME_EOF (-1)
+#define ME_ZERO (0)
+#define ME_RAMP (1)
+#define ME_STDY (2)
+
+struct {
+  double wpm, rise, fall, curr, incr, rate;
+  int type, size;
+} morsel;
+
+int ditspacesize, dahspacesize,
+    ditstdysize, dahstdysize,
+    charspacesize, wordspacesize,
+    risesize, fallsize;
+double riseincr, fallincr;
+
+#define MAX_ESC (512)
+#define ESC_L '<'
+#define ESC_R '>'
+
+void inlinecmd(char *, int);
+
+void send_sound(COMPLEX *, int);
+
+//------------------------------------------------------------
+
+// try to map char -> morse string
+char *
+get_morse(int c) { return morse_table[c & 0x7F]; }
+
+// translate text input to timed, sub-morse-element
+// audio segment specs; parcel the segments out
+// one at a time to the sound player
+void
+reader_thread(void) {
+  BOOLEAN b = TRUE; // we're coming from silence
+  int c, e;
+  char *m;
+  
+  // keep reading 1 char at a time
+  while ((c = getchar()) != EOF) {
+    
+    // inline command?
+    if (c == ESC_L) {
+      int i = 0;
+      char buf[MAX_ESC];
+      while ((c = getchar()) != EOF) {
+	if (c == ESC_R) break;
+	buf[i] = c;
+	if (++i >= (MAX_ESC - 1)) break;
+      }
+      if (c == EOF) goto finish;
+      buf[i] = 0;
+      inlinecmd(buf, i);
+      continue;
+    }
+
+    // is char mapped to morse?
+    if (m = get_morse(c)) {
+      
+      // yup
+      // for each element in morse string
+      // (dit/dah, doesn't matter)
+      while (e = *m++) {
+	// first segment is ramp up...
+	sem_wait(&reader);
+	morsel.type = ME_RAMP, morsel.size = risesize;
+	morsel.curr = 0.0, morsel.incr = riseincr;
+	sem_post(&writer);
+	
+	// ...then steady state...
+	// (choose dit/dah here)
+	sem_wait(&reader);
+	morsel.type = ME_STDY;
+	morsel.size = e == '.' ? ditstdysize : dahstdysize;
+	sem_post(&writer);
+	
+	// ...then ramp down...
+	sem_wait(&reader);
+	morsel.type = ME_RAMP, morsel.size = fallsize;
+	morsel.curr = 1.0, morsel.incr = fallincr;
+	sem_post(&writer);
+	
+	// ...finally, post-element pause
+	sem_wait(&reader);
+	morsel.type = ME_ZERO;
+	morsel.size = ditspacesize;
+	sem_post(&writer);
+      }
+      
+      // post-character pause
+      sem_wait(&reader);
+      morsel.type = ME_ZERO;
+      // (we already emitted a dit-sized space)
+      morsel.size = charspacesize - ditspacesize;
+      sem_post(&writer);
+      
+      // wherever we go next, it won't have been from silence
+      b = FALSE;
+
+    } else {
+      // anything else treated as interword space,
+      // which has only one segment (silence)
+      sem_wait(&reader);
+      morsel.type = ME_ZERO;
+      // was previous output also interword space?
+      if (b)
+	// yes, use full duration
+	morsel.size = wordspacesize;
+      else
+	// no, part of duration already played
+	morsel.size = wordspacesize - charspacesize;
+      b = TRUE;
+      sem_post(&writer);
+    }
+  }
+  
+ finish:
+  // indicate EOF on input
+  sem_wait(&reader);
+  morsel.type = ME_EOF;
+  sem_post(&writer);
+  pthread_exit(0);
+}
+
+void
+sound_thread_keyb(void) {
+  int i, k = 0;
+  double ofreq, scale, phase = 0.0;
+  COMPLEX z, delta_z;
+
+  // keep looking for sub-element segments, one at a time
+  for (;;) {
+
+    // pause for next sub-element segment
+    sem_post(&reader);
+    sem_wait(&writer);
+
+    // no more data?
+    if (morsel.type == ME_EOF) break;
+
+    // requires playing some tone?
+    if (morsel.type != ME_ZERO) {
+      // yes, reset params and
+      // set up CORDIC tone generation
+      ofreq = freq * 2.0 * M_PI / SAMP_RATE;
+      scale = pow(10.0, gain / 20.0);
+      if (phase > HUGE_PHASE) phase -= HUGE_PHASE;
+      z = Cmplx(cos(phase), sin(phase));
+      delta_z = Cmplx(cos(ofreq), sin(ofreq));
+    }
+
+    // play out this segment
+    for (i = 0; i < morsel.size; i++) {
+
+      // make silence
+      if (morsel.type == ME_ZERO) zout[k] = cxzero;
+      
+      // make tone
+      else {
+	z = Cmul(z, delta_z);
+	phase += ofreq;
+	// is this a ramping segment?
+	if (morsel.type == ME_RAMP) {
+	  morsel.curr += morsel.incr;
+	  zout[k] = Cscl(z, scale * sin(morsel.curr * M_PI / 2.0));
+	} else
+	  zout[k] = Cscl(z, scale);
+      }
+
+      // have we played enough to fill a jack buffer?
+      if (++k >= size) {
+	// yes, send to output
+	send_sound(zout, k);
+	// wait until some audio has been drained
+	sem_wait(&ready);
+	k = 0;
+	if (morsel.type != ME_ZERO) {
+	  // reset CORDIC
+	  if (phase > HUGE_PHASE) phase -= HUGE_PHASE;
+	  z = Cmplx(cos(phase), sin(phase));
+	  delta_z = Cmplx(cos(ofreq), sin(ofreq));
+	}
+      }
+    }
+  }
+
+  // anything left unsent?
+  if (k > 0) send_sound(zout, k);
+
+  pthread_exit(0);
+}
+
+//------------------------------------------------------------------------
+void
+send_sound(COMPLEX *buff, int len) {
+  if (ringb_write_space(lring) < len * sizeof(float)) {
+    //write(2, "overrun\n", 8);
+    ringb_restart(lring, size * sizeof(float));
+    ringb_restart(rring, size * sizeof(float));
+  } else {
+    int i;
+    for (i = 0; i < len; i++) {
+      float l = (float)buff[i].re, r = (float)buff[i].im;
+      ringb_write(lring, (char *) &l, sizeof(float));
+      ringb_write(rring, (char *) &r, sizeof(float));
+    }
+  }
+}
+#ifndef _WINDOWS
+PRIVATE void
+jack_xrun(void *arg) {
+  char *str = "xrun!\n";
+  write(2, str, strlen(str));
+}
+
+PRIVATE void
+jack_shutdown(void *arg) {}
+
+PRIVATE void
+jack_callback(jack_nframes_t nframes, void *arg) {
+  char *lp, *rp;
+  int nwant = nframes * sizeof(float),
+      nhave = ringb_read_space(lring);
+
+  lp = jack_port_get_buffer(lport, nframes);
+  rp = jack_port_get_buffer(rport, nframes);
+  if (nhave >= nwant) {
+    ringb_read(lring, lp, nwant);
+    ringb_read(rring, rp, nwant);
+    sem_post(&ready);
+  } else {
+    memset(lp, 0, nwant);
+    memset(rp, 0, nwant);
+  }
+}
+#endif
+void
+resetparam(void) {
+  morsel.wpm = wpm;
+  morsel.rise = morsel.fall = ramp;
+  morsel.rate = SAMP_RATE;
+
+  ditspacesize = (int)(SAMP_RATE * 1.2 / morsel.wpm + 0.5);
+  dahspacesize = (int)(3 * ditspacesize);
+  charspacesize = dahspacesize;
+  wordspacesize = 7 * ditspacesize;
+
+  risesize = (int)(SAMP_RATE * morsel.rise / 1e3 + 0.5);
+  if (risesize > 1)
+    riseincr = 1.0 / (risesize - 1);
+  else
+    riseincr = 1.0;
+
+  fallsize = (int)(SAMP_RATE * morsel.fall / 1e3 + 0.5);
+  if (fallsize > 1)
+    fallincr = -1.0 / (fallsize - 1);
+  else
+    fallincr = -1.0;
+
+  ditstdysize = ditspacesize - risesize - fallsize;
+  dahstdysize = dahspacesize - risesize - fallsize;
+}
+
+#ifndef _WINDOWS
+int
+main(int argc, char **argv) {
+  int i;
+
+  for (i = 1; i < argc; i++)
+    if (argv[i][0] == '-')
+      switch (argv[i][1]) {
+      case 'f':
+	freq = atof(argv[++i]);
+	break;
+      case 'w':
+	wpm = atof(argv[++i]);
+	break;
+      case 'r':
+	ramp = atof(argv[++i]);
+	break;
+      default:
+	fprintf(stderr, "keyd [-w wpm] [-f freq] [-r ramp_ms] [infile]\n");
+	exit(1);
+      }
+    else break;
+
+  if (i < argc) {
+    if (!freopen(argv[i], "r", stdin))
+      perror(argv[i]), exit(1);
+    i++;
+  }
+
+  //------------------------------------------------------------
+
+  resetparam();
+
+  //------------------------------------------------------------
+
+  if (!(client = jack_client_new("keyb")))
+    fprintf(stderr, "can't make client -- jack not running?\n"), exit(1);
+  jack_set_process_callback(client, (void *) jack_callback, 0);
+  jack_on_shutdown(client, (void *) jack_shutdown, 0);
+  jack_set_xrun_callback(client, (void *) jack_xrun, 0);
+  size = jack_get_buffer_size(client);
+
+  lport = jack_port_register(client,
+			     "ol",
+			     JACK_DEFAULT_AUDIO_TYPE,
+			     JackPortIsOutput,
+			     0);
+  rport = jack_port_register(client,
+			     "or",
+			     JACK_DEFAULT_AUDIO_TYPE,
+			     JackPortIsOutput,
+			     0);
+  lring = ringb_create(RING_SIZE);
+  rring = ringb_create(RING_SIZE);
+  ringb_clear(lring, size * sizeof(float));
+  ringb_clear(rring, size * sizeof(float));
+  
+  //------------------------------------------------------------
+
+  zout = newvec_COMPLEX(size, "keyb sample buffer");
+
+  //------------------------------------------------------------
+
+  sem_init(&ready, 0, 0);
+  sem_init(&reader, 0, 0);
+  sem_init(&writer, 0, 0);
+  pthread_create(&input, 0, (void *) reader_thread, 0);
+  pthread_create(&play, 0, (void *) sound_thread, 0);
+
+  //------------------------------------------------------------
+
+  jack_activate(client);
+  {
+    const char **ports;
+    if (!(ports = jack_get_ports(client, 0, 0, JackPortIsPhysical | JackPortIsInput))) {
+      fprintf(stderr, "can't find any physical playback ports\n");
+      exit(1);
+    }
+    if (jack_connect(client, jack_port_name(lport), ports[0])) {
+      fprintf(stderr, "can't connect left output\n");
+      exit(1);
+    }
+    if (jack_connect(client, jack_port_name(rport), ports[1])) {
+      fprintf(stderr, "can't connect right output\n");
+      exit(1);
+    }
+    free(ports);
+  }
+
+  pthread_join(input, 0);
+  pthread_join(play, 0);
+  jack_client_close(client);
+
+  //------------------------------------------------------------
+
+  delvec_COMPLEX(zout);
+
+  //------------------------------------------------------------
+
+  ringb_free(lring);
+  ringb_free(rring);
+  sem_destroy(&ready);
+  sem_destroy(&reader);
+  sem_destroy(&writer);
+
+  //------------------------------------------------------------
+
+  exit(0);
+}
+#endif
+char *morse_table[128] = {
+  /* 000 NUL */ 0, /* 001 SOH */ 0, /* 002 STX */ 0, /* 003 ETX */ 0,
+  /* 004 EOT */ 0, /* 005 ENQ */ 0, /* 006 ACK */ 0, /* 007 BEL */ 0,
+  /* 008  BS */ 0, /* 009  HT */ 0, /* 010  LF */ 0, /* 011  VT */ 0,
+  /* 012  FF */ 0, /* 013  CR */ 0, /* 014  SO */ 0, /* 015  SI */ 0,
+  /* 016 DLE */ 0, /* 017 DC1 */ 0, /* 018 DC2 */ 0, /* 019 DC3 */ 0,
+  /* 020 DC4 */ 0, /* 021 NAK */ 0, /* 022 SYN */ 0, /* 023 ETB */ 0,
+  /* 024 CAN */ 0, /* 025  EM */ 0, /* 026 SUB */ 0, /* 027 ESC */ 0,
+  /* 028  FS */ 0, /* 029  GS */ 0, /* 030  RS */ 0, /* 031  US */ 0,
+  /* 032  SP */ 0,
+  /* 033   ! */ "...-.",	// [SN]
+  /* 034   " */ 0,
+  /* 035   # */ 0,
+  /* 036   $ */ 0,
+  /* 037   % */ ".-...",	// [AS]
+  /* 038   & */ 0,
+  /* 039   ' */ 0,
+  /* 040   ( */ "-.--.",	// [KN]
+  /* 041   ) */ 0,
+  /* 042   * */ "...-.-",	// [SK]
+  /* 043   + */ ".-.-.",	// [AR]
+  /* 044   , */ "--..--",
+  /* 045   - */ "-....-",
+  /* 046   . */ ".-.-.-",
+  /* 047   / */ "-..-.",
+  /* 048   0 */ "-----",
+  /* 049   1 */ ".----",
+  /* 050   2 */ "..---",
+  /* 051   3 */ "...--",
+  /* 052   4 */ "....-",
+  /* 053   5 */ ".....",
+  /* 054   6 */ "-....",
+  /* 055   7 */ "--...",
+  /* 056   8 */ "---..",
+  /* 057   9 */ "----.",
+  /* 058   : */ 0,
+  /* 059   ; */ 0,
+  /* 060   < */ 0,
+  /* 061   = */ "-...-",	// [BT]
+  /* 062   > */ 0,
+  /* 063   ? */ "..__..",	// [IMI]
+  /* 064   @ */ ".--.-.",
+  /* 065   A */ ".-",
+  /* 066   B */ "-...",
+  /* 067   C */ "-.-.",
+  /* 068   D */ "-..",
+  /* 069   E */ ".",
+  /* 070   F */ "..-.",
+  /* 071   G */ "--.",
+  /* 072   H */ "....",
+  /* 073   I */ "..",
+  /* 074   J */ ".---",
+  /* 075   K */ "-.-",
+  /* 076   L */ ".-..",
+  /* 077   M */ "--",
+  /* 078   N */ "-.",
+  /* 079   O */ "---",
+  /* 080   P */ ".--.",
+  /* 081   Q */ "--.-",
+  /* 082   R */ ".-.",
+  /* 083   S */ "...",
+  /* 084   T */ "-",
+  /* 085   U */ "..-",
+  /* 086   V */ "...-",
+  /* 087   W */ ".--",
+  /* 088   X */ "-..-",
+  /* 089   Y */ "-.--",
+  /* 090   Z */ "--..",
+  /* 091   [ */ 0,
+  /* 092   \ */ 0,
+  /* 093   ] */ 0,
+  /* 094   ^ */ 0,
+  /* 095   _ */ 0,
+  /* 096   ` */ 0,
+  /* 097   a */ ".-",
+  /* 098   b */ "-...",
+  /* 099   c */ "-.-.",
+  /* 100   d */ "-..",
+  /* 101   e */ ".",
+  /* 102   f */ "..-.",
+  /* 103   g */ "--.",
+  /* 104   h */ "....",
+  /* 105   i */ "..",
+  /* 106   j */ ".---",
+  /* 107   k */ "-.-",
+  /* 108   l */ ".-..",
+  /* 109   m */ "--",
+  /* 110   n */ "-.",
+  /* 111   o */ "---",
+  /* 112   p */ ".--.",
+  /* 113   q */ "--.-",
+  /* 114   r */ ".-.",
+  /* 115   s */ "...",
+  /* 116   t */ "-",
+  /* 117   u */ "..-",
+  /* 118   v */ "...-",
+  /* 119   w */ ".--",
+  /* 120   x */ "-..-",
+  /* 121   y */ "-.--",
+  /* 122   z */ "--..",
+  /* 123   { */ 0,
+  /* 124   | */ 0,
+  /* 125   } */ 0,
+  /* 126   ~ */ 0,
+  /* 127 DEL */ 0
+};
+
+void
+inlinecmd(char *buf, int len) {
+  if (!buf || len < 1) return;
+  if (!strncmp(buf, "wpm", 3)) {
+    wpm = atof(buf + 3);
+    resetparam();
+  } else if (!strncmp(buf, "ramp", 4)) {
+    ramp = atof(buf + 4);
+    resetparam();
+  } else if (!strncmp(buf, "freq", 4))
+    freq = atof(buf + 4);
+  else if (!strncmp(buf, "gain", 4))
+    gain = atof(buf + 4);
+}
diff --git a/jDttSP/win/keyd.c b/jDttSP/win/keyd.c
new file mode 100644
index 0000000..f51dff8
--- /dev/null
+++ b/jDttSP/win/keyd.c
@@ -0,0 +1,342 @@
+/* keyd.c */
+/*
+This file is part of a program that implements a Software-Defined Radio.
+
+Copyright (C) 2004 by Frank Brickle, AB2KT and Bob McGwier, N4HY
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+The authors can be reached by email at
+
+ab2kt@arrl.net
+or
+rwmcgwier@comcast.net
+
+or by paper mail at
+
+The DTTS Microwave Society
+6 Kathleen Place
+Bridgewater, NJ 08807
+*/  
+
+//#include <linux/rtc.h>
+#include <fromsys.h>
+#include <banal.h>
+#include <splitfields.h>
+#include <datatypes.h>
+#include <bufvec.h>
+#include <cxops.h>
+#include <ringb.h>
+#include <chan.h>
+#include <oscillator.h>
+#include <cwtones.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <keyer.h>
+
+#define SAMP_RATE (48000)
+
+// # times key is sampled per sec
+// > 64 requires root on Linux
+//#define RTC_RATE (128)
+#define RTC_RATE (64)
+
+// # samples generated during 1 clock tick at RTC_RATE
+#define TONE_SIZE (SAMP_RATE / RTC_RATE)
+
+// ring buffer size; > 1 sec at this sr
+#define RING_SIZE (01 << 020)
+
+KeyerState ks;
+KeyerLogic kl;
+
+static pthread_t play, key, update;
+sem_t clock_fired, keyer_started, update_ok, poll_fired;
+
+int fdser, fdrtc;
+/*
+jack_client_t *client;
+jack_port_t *lport, *rport;
+jack_ringbuffer_t *lring, *rring;
+jack_nframes_t size; */
+ringb_t *lring, *rring;
+int size;
+
+CWToneGen gen;
+static BOOLEAN playing = FALSE, iambic = FALSE;
+static double wpm = 18.0, freq = 750.0, ramp = 5.0, gain = 1.0;
+
+//------------------------------------------------------------
+
+
+DttSP_EXP void
+CWtoneExchange(float *bufl,float*bufr,int nframes) {
+	size_t bytesize = nframes*4;
+	size_t numsamps;
+	if ((numsamps = ringb_read_space(lring)) < bytesize) {
+		memset(bufl,0,bytesize);
+		memset(bufr,0,bytesize);
+	} else {
+		ringb_read(lring,(char *)bufl,bytesize);
+		ringb_read(rring,(char *)bufr,bytesize);
+	}
+}
+
+//------------------------------------------------------------
+
+// generated tone -> output ringbuffer
+void
+send_tone(void) {
+  if (ringb_write_space(lring) < TONE_SIZE * sizeof(float)) {
+    //write(2, "overrun tone\n", 13);
+    ringb_restart(lring, TONE_SIZE * sizeof(float));
+    ringb_restart(rring, TONE_SIZE * sizeof(float));
+  } else {
+    int i;
+    for (i = 0; i < gen->size; i++) {
+      float l = (float)CXBreal(gen->buf, i),
+	    r = (float)CXBimag(gen->buf, i);
+      ringb_write(lring, (char *) &l, sizeof(float));
+      ringb_write(rring, (char *) &r, sizeof(float));
+    }
+  }
+}
+
+// silence -> output ringbuffer
+void
+send_silence(void) {
+  if (ringb_write_space(lring) < TONE_SIZE * sizeof(float)) {
+    //write(2, "overrun zero\n", 13);
+    ringb_restart(lring, TONE_SIZE * sizeof(float));
+    ringb_restart(rring, TONE_SIZE * sizeof(float));
+  } else {
+    int i;
+    for (i = 0; i < gen->size; i++) {
+      float zero = 0.0;
+      ringb_write(lring, (char *) &zero, sizeof(float));
+      ringb_write(rring, (char *) &zero, sizeof(float));
+    }
+  }
+}
+
+//------------------------------------------------------------------------
+
+// sound/silence generation
+// tone turned on/off asynchronously
+
+DttSP_EXP void
+sound_thread_keyd(void) {
+  for (;;) {
+    sem_wait(&clock_fired);
+
+    if (playing) {
+      // CWTone keeps playing for awhile after it's turned off,
+      // in order to allow for a decay envelope;
+      // returns FALSE when it's actually done.
+      playing = CWTone(gen);
+      send_tone();
+    } else {
+      send_silence();
+      // only let updates run when we've just generated silence
+//      sem_post(&update_ok);
+    }
+  }
+
+  pthread_exit(0);
+}
+
+
+BOOLEAN
+read_key(double del, BOOLEAN dot, BOOLEAN dash) {
+	extern BOOLEAN read_straight_key(KeyerState ks, BOOLEAN keyed);
+	extern BOOLEAN read_iambic_key(KeyerState ks, BOOLEAN dot, BOOLEAN dash, KeyerLogic kl, double ticklen);
+
+  if (iambic)
+    return read_iambic_key(ks, dot, dash, kl, del);
+  else
+    return read_straight_key(ks, dot^dash);
+}
+
+/// Main keyer function,  called by a thread in the C#
+DttSP_EXP void
+key_thread(double del, BOOLEAN dash, BOOLEAN dot) {
+	BOOLEAN keydown;
+
+    // called after next tick and passed the
+	// delay waitsince last one
+
+    // read key; tell keyer elapsed time since last call
+    keydown = read_key(del,dot,dash);
+
+
+    if (!playing && keydown)
+      CWToneOn(gen), playing = TRUE;
+    else if (playing && !keydown)
+      CWToneOff(gen);
+
+    sem_post(&clock_fired);
+}
+
+//------------------------------------------------------------------------
+
+// update keyer parameters via text input from stdin
+// <wpm xxx> -> set keyer speed to xxx
+// <gain xxx> -> set gain to xxx (dB)
+// <freq xxx> -> set freq to xxx
+// <ramp xxx> -> set attack/decay times to xxx ms
+
+
+#define MAX_ESC (512)
+#define ESC_L '<'
+#define ESC_R '>'
+
+void
+updater(void) {
+  for (;;) {
+    int c;
+
+    // get or wait for next input char
+    if ((c = getchar()) == EOF) goto finish;
+
+    // if we see the beginning of a command,
+    if (c == ESC_L) {
+      int i = 0;
+      char buf[MAX_ESC];
+
+      // gather up the remainder
+      while ((c = getchar()) != EOF) {
+	if (c == ESC_R) break;
+	buf[i] = c;
+	if (++i >= (MAX_ESC - 1)) break;
+      }
+      if (c == EOF) goto finish;
+      buf[i] = 0;
+
+      // wait until changes are safe
+      sem_wait(&update_ok);
+
+      if (!strncmp(buf, "wpm", 3))
+	ks->wpm = wpm = atof(buf + 3);
+      else if (!strncmp(buf, "ramp", 4)) {
+	ramp = atof(buf + 4);
+	setCWToneGenVals(gen, gain, freq, ramp, ramp);
+      } else if (!strncmp(buf, "freq", 4)) {
+	freq = atof(buf + 4);
+	setCWToneGenVals(gen, gain, freq, ramp, ramp);
+      } else if (!strncmp(buf, "gain", 4)) {
+	gain = atof(buf + 4);
+	setCWToneGenVals(gen, gain, freq, ramp, ramp);
+      } else if (!strncmp(buf, "quit", 4))
+	goto finish;
+
+    } // otherwise go around again
+  }
+
+  // we saw an EOF or quit; kill other threads and exit neatly
+
+ finish:
+  pthread_cancel(play);
+  pthread_cancel(key);
+  pthread_exit(0);
+}
+DttSP_EXP void
+updateKeyer(double nfreq, BOOLEAN niambic, double ngain, double nramp, double nwpm,
+			BOOLEAN revpdl, int weight, double SampleRate) {
+	ks->flag.iambic = niambic;
+	iambic = niambic;
+	ks->flag.revpdl = revpdl;
+	ks->weight = weight;
+	wpm = nwpm;
+	gain = ngain;
+	ramp = nramp;
+	freq = nfreq;
+	gen->osc.freq = 2.0 * M_PI * freq / SampleRate;
+}
+DttSP_EXP void
+NewKeyer(double freq, BOOLEAN niambic, double gain, double ramp, double wpm, double SampleRate) {
+
+  void *usemem;
+
+ //------------------------------------------------------------
+
+  gen = newCWToneGen(gain, freq, ramp, ramp, TONE_SIZE, SampleRate);
+
+  //------------------------------------------------------------
+
+  kl = newKeyerLogic();
+  ks = newKeyerState();
+  ks->flag.iambic = niambic;
+  ks->flag.revpdl = TRUE; // depends on port wiring
+  ks->flag.autospace.khar = ks->flag.autospace.word = FALSE;
+  ks->debounce = 1; // could be more if sampled faster
+  ks->mode = MODE_B;
+  ks->weight = 50;
+  ks->wpm = wpm;
+  iambic = niambic;
+  size = 2048;
+  usemem = safealloc(1,4096*sizeof(float)+sizeof(ringb_t),"Keyer RB Left");
+  lring = ringb_create(usemem, 4096*sizeof(float));
+  usemem = safealloc(1,4096*sizeof(float)+sizeof(ringb_t),"Keyer RB Right");
+  rring = ringb_create(usemem,4096*sizeof(float));
+  ringb_clear(lring, size * sizeof(float));
+  ringb_clear(rring, size * sizeof(float));
+  sem_init(&clock_fired, 0, 0);
+  sem_init(&poll_fired , 0, 0);
+  sem_init(&keyer_started,0,0);
+}
+
+DttSP_EXP void
+delKeyer() {
+  sem_destroy(&clock_fired);
+  sem_destroy(&poll_fired);
+  sem_destroy(&keyer_started);
+  delCWToneGen(gen);
+  delKeyerState(ks);
+  delKeyerLogic(kl);
+  safefree((char *)lring);
+  safefree((char *)rring);
+}
+DttSP_EXP void
+KeyerClockFireWait()
+{
+	sem_wait(&clock_fired);
+}
+DttSP_EXP void
+KeyerClockFireRelease()
+{
+	sem_post(&clock_fired);
+}
+DttSP_EXP void
+KeyerStartedWait()
+{
+	sem_wait(&keyer_started);
+}
+DttSP_EXP void
+KeyerStartedRelease()
+{
+	sem_post(&keyer_started);
+}
+DttSP_EXP void
+PollTimerWait()
+{
+	sem_wait(&poll_fired);
+}
+DttSP_EXP void
+PollTimerRelease()
+{
+	sem_post(&poll_fired);
+}
+
+//------------------------------------------------------------------------
diff --git a/jDttSP/win/keyerio.c b/jDttSP/win/keyerio.c
new file mode 100644
index 0000000..4fe2a61
--- /dev/null
+++ b/jDttSP/win/keyerio.c
@@ -0,0 +1,91 @@
+#include <keyer.h>
+
+//========================================================================
+
+/* Read a straight key connected to a serial port, do debouncing, then
+   return the key state */
+
+BOOLEAN
+read_straight_key(KeyerState ks, BOOLEAN keyed) {
+  int i, j;
+  static BOOLEAN keystate = 0;
+  static int debounce_buf_i = 0,
+             debounce_buf[DEBOUNCE_BUF_MAX_SIZE];
+  debounce_buf[debounce_buf_i] = keyed;
+  debounce_buf_i++;
+
+  //
+  //***************************************************
+  // back to business as usual
+  //***************************************************
+
+  /* If the debounce buffer is full, determine the state of the key */
+  if (debounce_buf_i >= ks->debounce) {
+    debounce_buf_i = 0;
+
+    j = 0;
+    for (i = 0; i < ks->debounce; i++)
+      if (debounce_buf[i])
+	j++;
+    keystate = (j > ks->debounce / 2) ? 1 : 0;
+  }
+
+  return keystate;
+}
+
+//------------------------------------------------------------------------
+
+/* Read an iambic key connected to a serial port, do debouncing, emulate a
+   straight key, then return the emulated key state */
+
+BOOLEAN
+read_iambic_key(KeyerState ks, BOOLEAN dash, BOOLEAN dot, KeyerLogic kl, double ticklen) {
+  int i, j;
+  static BOOLEAN dah_debounce_buf[DEBOUNCE_BUF_MAX_SIZE],
+                 dit_debounce_buf[DEBOUNCE_BUF_MAX_SIZE];
+  static int dah = 0, debounce_buf_i = 0, dit = 0;
+  
+  if (ks->flag.revpdl) {
+	dah_debounce_buf[debounce_buf_i] = dot;
+	dit_debounce_buf[debounce_buf_i] = dash;
+  } else {
+ 	dah_debounce_buf[debounce_buf_i] = dash;
+	dit_debounce_buf[debounce_buf_i] = dot;
+  }
+  debounce_buf_i++;
+ 
+  //
+  //***************************************************
+  // back to business as usual
+  //***************************************************
+
+  /* If the debounce buffer is full, determine the state of the keys */
+  if (debounce_buf_i >= ks->debounce) {
+    debounce_buf_i = 0;
+
+    j = 0;
+    for (i = 0; i < ks->debounce; i++)
+      if (dah_debounce_buf[i]) j++;
+    dah = (j > ks->debounce / 2) ? 1 : 0;
+
+    j = 0;
+    for (i = 0; i < ks->debounce; i++)
+      if (dit_debounce_buf[i]) j++;
+    dit = (j > ks->debounce / 2) ? 1 : 0;
+  }
+
+  return klogic(kl,
+		dit,
+		dah,
+		ks->wpm,
+		ks->mode,
+		ks->flag.mdlmdB,
+		ks->flag.memory.dit,
+		ks->flag.memory.dah,
+		ks->flag.autospace.khar,
+		ks->flag.autospace.word,
+		ks->weight,
+		ticklen);
+}
+
+//========================================================================
diff --git a/jDttSP/win/local.h b/jDttSP/win/local.h
new file mode 100644
index 0000000..0c0e2e3
--- /dev/null
+++ b/jDttSP/win/local.h
@@ -0,0 +1,72 @@
+/* local.h
+
+Some manifest constants for the particular implementation
+   
+This file is part of a program that implements a Software-Defined Radio.
+
+Copyright (C) 2004 by Frank Brickle, AB2KT and Bob McGwier, N4HY
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+The authors can be reached by email at
+
+ab2kt@arrl.net
+or
+rwmcgwier@comcast.net
+
+or by paper mail at
+
+The DTTS Microwave Society
+6 Kathleen Place
+Bridgewater, NJ 08807
+*/
+
+/* #include <fromsys.h> */
+/* #include <datatypes.h> */
+/* #include <banal.h> */
+/* #include <fftw.h> */
+/* #include <sdrexport.h> */
+
+#ifndef _local_h
+#define _local_h
+
+#include <common.h>
+//\\.\pipe\pipename
+#define RCBASE ".DttSPrc"
+#define PARMPATH  "\\\\.\\pipe\\SDRcommands"
+#define METERPATH "\\\\.\\pipe\\SDRmeter"
+#define SPECPATH  "\\\\.\\pipe\\SDRspectrum"
+#define WISDOMPATH ".\\wisdom"
+
+
+extern struct _loc {
+  char name[MAXPATHLEN];
+  struct {
+    char rcfile[MAXPATHLEN],
+         parm[MAXPATHLEN],
+         meter[MAXPATHLEN],
+         spec[MAXPATHLEN],
+         wisdom[MAXPATHLEN];
+  } path;
+  struct {
+    REAL rate;
+    int size, nrx, spec, comp;
+    SDRMODE mode;
+  } def;
+  struct { int ring;} mult;
+} loc;
+
+
+#endif
diff --git a/jDttSP/win/sdr.c b/jDttSP/win/sdr.c
new file mode 100644
index 0000000..9f52144
--- /dev/null
+++ b/jDttSP/win/sdr.c
@@ -0,0 +1,865 @@
+/* sdr.c
+
+This file is part of a program that implements a Software-Defined Radio.
+
+Copyright (C) 2004 by Frank Brickle, AB2KT and Bob McGwier, N4HY
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+The authors can be reached by email at
+
+ab2kt@arrl.net
+or
+rwmcgwier@comcast.net
+
+or by paper mail at
+
+The DTTS Microwave Society
+6 Kathleen Place
+Bridgewater, NJ 08807
+*/
+
+#include <common.h>
+
+//========================================================================
+/* initialization and termination */
+
+void
+reset_meters(void) {  
+  if (uni.meter.flag) { // reset metering completely
+    int i, k;
+    for (i = 0; i < RXMETERPTS; i++)
+      for (k = 0; k < MAXRX; k++)
+	uni.meter.rx.val[k][i] = uni.meter.rx.avg[k][i] = -200.0;
+    for (i = 0; i < TXMETERPTS; i++)
+      uni.meter.tx.val[i] = uni.meter.tx.avg[i] = -200.0;
+  }
+}
+
+void
+reset_spectrum(void) {  
+  if (uni.spec.flag)
+    reinit_spectrum(&uni.spec);
+}
+
+void
+reset_counters(void) {
+  int k;
+  for (k = 0; k < uni.multirx.nrx; k++) rx[k].tick = 0;
+  tx.tick = 0;
+}
+
+//========================================================================
+
+/* global and general info,
+   not specifically attached to
+   tx, rx, or scheduling */
+
+PRIVATE void
+setup_all(void) {
+  
+  uni.samplerate = loc.def.rate;
+  uni.buflen = loc.def.size;
+  uni.mode.sdr = loc.def.mode;
+  uni.mode.trx = RX;
+  
+  uni.wisdom.path = loc.path.wisdom;
+  uni.wisdom.bits = FFTW_OUT_OF_PLACE | FFTW_ESTIMATE;
+  {
+    FILE *f = fopen(uni.wisdom.path, "r");
+    if (f) {
+#define WBUFLEN 2048
+#define WSTRLEN 64      
+      char *line = (char *)malloc(WBUFLEN);
+      fgets(line, WBUFLEN, f);
+      if ((strlen(line) > WSTRLEN) &&
+	  (fftw_import_wisdom_from_string(line) != FFTW_FAILURE))
+	uni.wisdom.bits = FFTW_OUT_OF_PLACE | FFTW_MEASURE | FFTW_USE_WISDOM;
+#undef WSTRLEN
+#undef WBUFLEN      
+      fclose(f);
+	  free(line);
+    }
+
+  }
+  
+  if (uni.meter.flag) {
+    uni.meter.rx.type = SIGNAL_STRENGTH;
+    uni.meter.tx.type = SIGNAL_STRENGTH;
+    reset_meters();
+  }
+  
+  uni.spec.rxk = 0;
+  uni.spec.buflen = uni.buflen;
+  uni.spec.scale = SPEC_PWR;
+  uni.spec.type = SPEC_POST_FILT;
+  uni.spec.size = loc.def.spec;
+  uni.spec.planbits = uni.wisdom.bits;
+  init_spectrum(&uni.spec);
+  
+  // set which receiver is listening to commands
+  uni.multirx.lis = 0;
+  uni.multirx.nrx = loc.def.nrx;
+  
+  // set mixing of input from aux ports
+  uni.mix.rx.flag = uni.mix.tx.flag = FALSE;
+  uni.mix.rx.gain = uni.mix.tx.gain = 1.0;
+  
+  uni.tick = 0;
+}
+
+/* purely rx */
+
+PRIVATE void
+setup_rx(int k) {
+  
+  /* conditioning */
+  rx[k].iqfix = newCorrectIQ(0.0, 1.0);
+  rx[k].filt.coef = newFIR_Bandpass_COMPLEX(-4800.0,
+					    4800.0,
+					    uni.samplerate,
+					    uni.buflen + 1);
+  rx[k].filt.ovsv = newFiltOvSv(FIRcoef(rx[k].filt.coef),
+				FIRsize(rx[k].filt.coef),
+				uni.wisdom.bits);
+  normalize_vec_COMPLEX(rx[k].filt.ovsv->zfvec,
+			rx[k].filt.ovsv->fftlen);
+
+  // hack for EQ
+  rx[k].filt.save = newvec_COMPLEX(rx[k].filt.ovsv->fftlen, "RX filter cache");
+  memcpy((char *) rx[k].filt.save,
+	 (char *) rx[k].filt.ovsv->zfvec,
+	 rx[k].filt.ovsv->fftlen * sizeof(COMPLEX));
+
+  /* buffers */
+  /* note we overload the internal filter buffers
+     we just created */
+  rx[k].buf.i = newCXB(FiltOvSv_fetchsize(rx[k].filt.ovsv),
+		       FiltOvSv_fetchpoint(rx[k].filt.ovsv),
+		       "init rx.buf.i");
+  rx[k].buf.o = newCXB(FiltOvSv_storesize(rx[k].filt.ovsv),
+		       FiltOvSv_storepoint(rx[k].filt.ovsv),
+		       "init rx[k].buf.o");
+  
+  /* conversion */
+  rx[k].osc.freq = -11025.0;
+  rx[k].osc.phase = 0.0;
+  rx[k].osc.gen = newOSC(uni.buflen,
+			 ComplexTone,
+			 rx[k].osc.freq,
+			 rx[k].osc.phase,
+			 uni.samplerate,
+			 "SDR RX Oscillator");
+
+  rx[k].agc.gen = newDigitalAgc(agcMED,	// Mode
+			     7,		// Hang
+			     7,		// Size
+			     48,	// Ramp
+			     3,		// Over
+			     3,		// Rcov
+			     CXBsize(rx[k].buf.o),	// BufSize
+			     100.0,	// MaxGain
+			     0.707,	// Limit
+			     1.0,	// CurGain
+			     CXBbase(rx[k].buf.o));
+  rx[k].agc.flag = TRUE;
+
+  /* demods */
+  rx[k].am.gen = newAMD(48000.0,	// REAL samprate
+			0.0,	// REAL f_initial
+			-500.0,	// REAL f_lobound,
+			500.0,	// REAL f_hibound,
+			400.0,	// REAL f_bandwid,
+			CXBsize(rx[k].buf.o),	// int size,
+			CXBbase(rx[k].buf.o),	// COMPLEX *ivec,
+			CXBbase(rx[k].buf.o),	// COMPLEX *ovec,
+			AMdet,	// AM Mode AMdet == rectifier,
+		                //         SAMdet == synchronous detector
+			"AM detector blew");	// char *tag
+  rx[k].fm.gen = newFMD(48000,	// REAL samprate
+			0.0,	// REAL f_initial
+			-6000.0,	// REAL f_lobound
+			6000.0,	// REAL f_hibound
+			10000.0,	// REAL f_bandwid
+			CXBsize(rx[k].buf.o),	// int size
+			CXBbase(rx[k].buf.o),	// COMPLEX *ivec
+			CXBbase(rx[k].buf.o),	// COMPLEX *ovec
+			"New FM Demod structure");	// char *error message;
+
+  /* noise reduction */
+  rx[k].anf.gen = new_lmsr(rx[k].buf.o,	// CXB signal,
+			   64,		// int delay,
+			   0.01,		// REAL adaptation_rate,
+			   0.00001,	// REAL leakage,
+			   45,		// int adaptive_filter_size,
+			   LMADF_INTERFERENCE);
+  rx[k].anf.flag = FALSE;
+  rx[k].anr.gen = new_lmsr(rx[k].buf.o,	// CXB signal,
+			   64,		// int delay,
+			   0.01,		// REAL adaptation_rate,
+			   0.00001,	// REAL leakage,
+			   45,		// int adaptive_filter_size,
+			   LMADF_NOISE);
+  rx[k].anr.flag = FALSE;
+
+  rx[k].nb.thresh = 3.3;
+  rx[k].nb.gen = new_noiseblanker(rx[k].buf.i, rx[k].nb.thresh);
+  rx[k].nb.flag = FALSE;
+
+  rx[k].nb_sdrom.thresh = 2.5;
+  rx[k].nb_sdrom.gen = new_noiseblanker(rx[k].buf.i, rx[k].nb_sdrom.thresh);
+  rx[k].nb_sdrom.flag = FALSE;
+
+  rx[k].spot.gen = newSpotToneGen(-12.0,	// gain
+				  700.0,	// freq
+				  5.0,	// ms rise
+				  5.0,	// ms fall
+				  uni.buflen,
+				  uni.samplerate);
+
+  rx[k].scl.pre.val = 1.0;
+  rx[k].scl.pre.flag = FALSE;
+  rx[k].scl.post.val = 1.0;
+  rx[k].scl.post.flag = FALSE;
+
+  memset((char *) &rx[k].squelch, 0, sizeof(rx[k].squelch));
+  rx[k].squelch.thresh = -30.0;
+  rx[k].squelch.power = 0.0;
+  rx[k].squelch.flag = rx[k].squelch.running = rx[k].squelch.set = FALSE;
+  rx[k].squelch.num = (int) (0.0395 * uni.samplerate + 0.5);
+
+  rx[k].mode = uni.mode.sdr;
+  rx[k].bin.flag = FALSE;
+
+  {
+    REAL pos = 0.5, // 0 <= pos <= 1, left->right
+         theta = (1.0 - pos) * M_PI / 2.0;
+    rx[k].azim = Cmplx(cos(theta), sin(theta));
+  }
+
+  rx[k].tick = 0;
+}
+
+/* purely tx */
+
+PRIVATE void
+setup_tx(void) {
+
+  /* conditioning */
+  tx.iqfix = newCorrectIQ(0.0, 1.0);
+  tx.filt.coef = newFIR_Bandpass_COMPLEX(300.0,
+					 3000.0,
+					 uni.samplerate,
+					 uni.buflen + 1);
+  tx.filt.ovsv = newFiltOvSv(FIRcoef(tx.filt.coef),
+			     FIRsize(tx.filt.coef),
+			     uni.wisdom.bits);
+  normalize_vec_COMPLEX(tx.filt.ovsv->zfvec,
+			tx.filt.ovsv->fftlen);
+
+  // hack for EQ
+  tx.filt.save = newvec_COMPLEX(tx.filt.ovsv->fftlen, "TX filter cache");
+  memcpy((char *) tx.filt.save,
+	 (char *) tx.filt.ovsv->zfvec,
+	 tx.filt.ovsv->fftlen * sizeof(COMPLEX));
+
+  /* buffers */
+  tx.buf.i = newCXB(FiltOvSv_fetchsize(tx.filt.ovsv),
+		    FiltOvSv_fetchpoint(tx.filt.ovsv),
+		    "init tx.buf.i");
+  tx.buf.o = newCXB(FiltOvSv_storesize(tx.filt.ovsv),
+		    FiltOvSv_storepoint(tx.filt.ovsv),
+		    "init tx.buf.o");
+  
+  /* conversion */
+  tx.osc.freq = 0.0;
+  tx.osc.phase = 0.0;
+  tx.osc.gen = newOSC(uni.buflen,
+		      ComplexTone,
+		      tx.osc.freq,
+		      tx.osc.phase,
+		      uni.samplerate,
+		      "SDR TX Oscillator");
+
+  tx.agc.gen = newDigitalAgc(agcFAST, 	// Mode
+			     3,		// Hang
+			     3,		// Size
+			     3,		// Over
+			     3,		// Rcov
+			     48,	// Ramp
+			     CXBsize(tx.buf.o),	// BufSize
+			     1.0,	// MaxGain
+			     0.900,	// Limit
+			     1.0,	// CurGain
+			     CXBbase(tx.buf.o));
+  tx.agc.flag = TRUE;
+
+  tx.spr.gen = newSpeechProc(0.4, 10.0, CXBbase(tx.buf.i), CXBsize(tx.buf.i));
+  tx.spr.flag = FALSE;
+
+  tx.scl.dc = cxzero;
+  tx.scl.pre.val = 1.0;
+  tx.scl.pre.flag = FALSE;
+  tx.scl.post.val = 1.0;
+  tx.scl.post.flag = FALSE;
+
+  tx.mode = uni.mode.sdr;
+
+  tx.tick = 0;
+  /* not much else to do for TX */
+}
+
+/* how the outside world sees it */
+
+void
+setup_workspace(void) {
+  int k;
+
+  setup_all();
+
+  for (k = 0; k < uni.multirx.nrx; k++) {
+    setup_rx(k);
+    uni.multirx.act[k] = FALSE;
+  }
+  uni.multirx.act[0] = TRUE;
+  uni.multirx.nac = 1;
+  
+  setup_tx();
+}
+
+void
+destroy_workspace(void) {
+  int k;
+
+  /* TX */
+  delSpeechProc(tx.spr.gen);
+  delDigitalAgc(tx.agc.gen);
+  delOSC(tx.osc.gen);
+  delvec_COMPLEX(tx.filt.save);
+  delFiltOvSv(tx.filt.ovsv);
+  delFIR_Bandpass_COMPLEX(tx.filt.coef);
+  delCorrectIQ(tx.iqfix);
+  delCXB(tx.buf.o);
+  delCXB(tx.buf.i);
+
+  /* RX */
+  for (k = 0; k < uni.multirx.nrx; k++) {
+    delSpotToneGen(rx[k].spot.gen);
+    delDigitalAgc(rx[k].agc.gen);
+    del_nb(rx[k].nb_sdrom.gen);
+    del_nb(rx[k].nb.gen);
+    del_lmsr(rx[k].anf.gen);
+    del_lmsr(rx[k].anr.gen);
+    delAMD(rx[k].am.gen);
+    delFMD(rx[k].fm.gen);
+    delOSC(rx[k].osc.gen);
+    delvec_COMPLEX(rx[k].filt.save);
+    delFiltOvSv(rx[k].filt.ovsv);
+    delFIR_Bandpass_COMPLEX(rx[k].filt.coef);
+    delCorrectIQ(rx[k].iqfix);
+    delCXB(rx[k].buf.o);
+    delCXB(rx[k].buf.i);
+  }
+  
+  /* all */
+  finish_spectrum(&uni.spec);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// execution
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// util
+
+PRIVATE REAL
+CXBnorm(CXB buff) {
+  int i;
+  double sum = 0.0;
+  for (i = 0; i < CXBhave(buff); i++)
+    sum += Csqrmag(CXBdata(buff, i));
+  return sqrt(sum);
+}
+
+//========================================================================
+/* all */
+
+// unfortunate duplication here, due to
+// multirx vs monotx
+
+PRIVATE void
+do_rx_meter(int k, CXB buf, int tap) {
+  COMPLEX *vec = CXBbase(buf);
+  int i, len = CXBhave(buf);
+  
+  uni.meter.rx.val[k][tap] = 0;
+  
+  switch (uni.meter.rx.type) {
+  case AVG_SIGNAL_STRENGTH:
+    for (i = 0; i < len; i++)
+      uni.meter.rx.val[k][tap] += Csqrmag(vec[i]);
+    uni.meter.rx.val[k][tap] =
+      uni.meter.rx.avg[k][tap] =
+        0.9 * uni.meter.rx.avg[k][tap] + log10(uni.meter.rx.val[k][tap] + 1e-20);
+    break;
+  case SIGNAL_STRENGTH:
+    for (i = 0; i < len; i++)
+      uni.meter.rx.val[k][tap] += Csqrmag(vec[i]);
+    uni.meter.rx.avg[k][tap] =
+      uni.meter.rx.val[k][tap] =
+        10.0 * log10(uni.meter.rx.val[k][tap] + 1e-20);
+    break;
+  case ADC_REAL:
+    for(i = 0; i < len; i++)
+      uni.meter.rx.val[k][tap] = max(fabs(vec[i].re), uni.meter.rx.val[k][tap]);
+    uni.meter.rx.val[k][tap] = 20.0 * log10(uni.meter.rx.val[k][tap] + 1e-10);
+    break;
+  case ADC_IMAG:
+    for(i = 0; i < len; i++)
+      uni.meter.rx.val[k][tap] = max(fabs(vec[i].im), uni.meter.rx.val[k][tap]);
+    uni.meter.rx.val[k][tap] = 20.0 * log10(uni.meter.rx.val[k][tap] + 1e-10);
+    break;
+  default:
+    break;
+  }
+}
+
+PRIVATE void
+do_tx_meter(CXB buf, int tap) {
+  COMPLEX *vec = CXBbase(buf);
+  int i, len = CXBhave(buf);
+  
+  uni.meter.tx.val[tap] = 0;
+
+  switch (uni.meter.tx.type) {
+  case AVG_SIGNAL_STRENGTH:
+    for (i = 0; i < len; i++)
+      uni.meter.tx.val[tap] += Csqrmag(vec[i]);
+    uni.meter.tx.val[tap] =
+      uni.meter.tx.avg[tap] =
+        0.9 * uni.meter.tx.avg[tap] + log10(uni.meter.tx.val[tap] + 1e-20);
+    break;
+  case SIGNAL_STRENGTH:
+    for (i = 0; i < len; i++)
+      uni.meter.tx.val[tap] += Csqrmag(vec[i]);
+    uni.meter.tx.avg[tap] =
+      uni.meter.tx.val[tap] =
+        10.0 * log10(uni.meter.tx.val[tap] + 1e-20);
+    break;
+  case ADC_REAL:
+    for(i = 0; i < len; i++)
+      uni.meter.tx.val[tap] = max(fabs(vec[i].re), uni.meter.tx.val[tap]);
+    uni.meter.tx.val[tap] = 20.0 * log10(uni.meter.tx.val[tap] + 1e-10);
+    break;
+  case ADC_IMAG:
+    for(i = 0; i < len; i++)
+      uni.meter.tx.val[tap] = max(fabs(vec[i].im), uni.meter.tx.val[tap]);
+    uni.meter.tx.val[tap] = 20.0 * log10(uni.meter.tx.val[tap] + 1e-10);
+    break;
+  default:
+    break;
+  }
+}
+
+PRIVATE void
+do_rx_spectrum(int k, CXB buf, int type) {
+  if (uni.spec.flag && k == uni.spec.rxk && type == uni.spec.type) {
+    memcpy((char *) &CXBdata(uni.spec.accum, uni.spec.fill),
+	   (char *) CXBbase(buf),
+	   CXBhave(buf)); 
+    uni.spec.fill = (uni.spec.fill + uni.spec.buflen) % uni.spec.size;
+  }
+}
+
+PRIVATE void
+do_tx_spectrum(CXB buf) {
+  memcpy((char *) &CXBdata(uni.spec.accum, uni.spec.fill),
+	 (char *) CXBbase(buf),
+	 CXBhave(buf));
+  uni.spec.fill = (uni.spec.fill + uni.spec.buflen) % uni.spec.size;
+}
+
+//========================================================================
+/* RX processing */ 
+
+PRIVATE BOOLEAN
+should_do_rx_squelch(int k) {
+  if (rx[k].squelch.flag) {
+    int i, n = CXBhave(rx[k].buf.o);
+    rx[k].squelch.power = 0.0;
+    for (i = 0; i < n; i++)
+      rx[k].squelch.power += Csqrmag(CXBdata(rx[k].buf.o, i));
+    return rx[k].squelch.thresh > 10.0 * log10(rx[k].squelch.power);
+  } else
+    return rx[k].squelch.set = FALSE;
+}
+
+// apply squelch
+// slew into silence first time
+
+PRIVATE void
+do_squelch(int k) {
+  rx[k].squelch.set = TRUE;
+  if (!rx[k].squelch.running) {
+    int i, m = rx[k].squelch.num, n = CXBhave(rx[k].buf.o) - m;
+    for (i = 0; i < m; i++)
+      CXBdata(rx[k].buf.o, i) = Cscl(CXBdata(rx[k].buf.o, i), 1.0 - (REAL) i / m);
+    memset((void *) (CXBbase(rx[k].buf.o) + m), 0, n * sizeof(COMPLEX));
+    rx[k].squelch.running = TRUE;
+  } else
+    memset((void *) CXBbase(rx[k].buf.o), 0, CXBhave(rx[k].buf.o) * sizeof(COMPLEX));
+}
+
+// lift squelch
+// slew out from silence to full scale
+
+PRIVATE void
+no_squelch(int k) {
+  if (rx[k].squelch.running) {
+    int i, m = rx[k].squelch.num;
+    for (i = 0; i < m; i++)
+      CXBdata(rx[k].buf.o, i) = Cscl(CXBdata(rx[k].buf.o, i), (REAL) i / m);
+    rx[k].squelch.running = FALSE;
+  }
+}
+
+/* pre-condition for (nearly) all RX modes */
+
+PRIVATE void
+do_rx_pre(int k) {
+  int i, n = min(CXBhave(rx[k].buf.i), uni.buflen);
+
+  if (rx[k].scl.pre.flag)
+    for (i = 0; i < n; i++)
+      CXBdata(rx[k].buf.i, i) = Cscl(CXBdata(rx[k].buf.i, i),
+				     rx[k].scl.pre.val); 
+
+  if (rx[k].nb.flag) noiseblanker(rx[k].nb.gen);
+  if (rx[k].nb_sdrom.flag) SDROMnoiseblanker(rx[k].nb_sdrom.gen);
+
+  // metering for uncorrected values here
+
+  do_rx_meter(k, rx[k].buf.i, RXMETER_PRE_CONV);
+
+  correctIQ(rx[k].buf.i, rx[k].iqfix);
+
+  /* 2nd IF conversion happens here */
+
+  if (rx[k].osc.gen->Frequency != 0.0) {
+    ComplexOSC(rx[k].osc.gen);
+    for (i = 0; i < n; i++)
+      CXBdata(rx[k].buf.i, i) = Cmul(CXBdata(rx[k].buf.i, i),
+				     OSCCdata(rx[k].osc.gen, i));
+  } 
+
+  /* filtering, metering, spectrum, squelch, & AGC */
+  
+  if (rx[k].mode == SPEC)
+    
+    do_rx_spectrum(k, rx[k].buf.i, SPEC_SEMI_RAW);
+  
+  else {
+    
+    do_rx_meter(k, rx[k].buf.i, RXMETER_PRE_FILT);
+    do_rx_spectrum(k, rx[k].buf.i, SPEC_PRE_FILT);
+    
+    if (rx[k].tick == 0)
+      reset_OvSv(rx[k].filt.ovsv);
+    
+    filter_OvSv(rx[k].filt.ovsv);
+    CXBhave(rx[k].buf.o) = CXBhave(rx[k].buf.i);
+    
+    do_rx_meter(k, rx[k].buf.o, RXMETER_POST_FILT);
+    do_rx_spectrum(k, rx[k].buf.o, SPEC_POST_FILT);
+    
+    if (should_do_rx_squelch(k))
+      do_squelch(k);
+    
+    else if (rx[k].agc.flag)
+      DigitalAgc(rx[k].agc.gen, rx[k].tick);
+    
+  }
+}
+
+PRIVATE void
+do_rx_post(int k) {
+  int i, n = CXBhave(rx[k].buf.o);
+  
+  if (!rx[k].squelch.set)  {
+    no_squelch(k);
+    // spotting tone
+    if (rx[k].spot.flag) {
+      // remember whether it's turned itself off during this pass
+      rx[k].spot.flag = SpotTone(rx[k].spot.gen);
+      for (i = 0; i < n; i++)
+	CXBdata(rx[k].buf.o, i) = Cadd(CXBdata(rx[k].buf.o, i),
+				       CXBdata(rx[k].spot.gen->buf, i));
+    }
+  }
+  
+  // final scaling
+  
+  if (rx[k].scl.post.flag)
+    for (i = 0; i < n; i++)
+      CXBdata(rx[k].buf.o, i) = Cscl(CXBdata(rx[k].buf.o, i),
+				     rx[k].scl.post.val);
+  
+  // not binaural?
+  // position in stereo field
+  
+  if (!rx[k].bin.flag)
+    for (i = 0; i < n; i++)
+      CXBdata(rx[k].buf.o, i) = Cscl(rx[k].azim, CXBreal(rx[k].buf.o, i));
+}
+
+/* demod processing */
+
+PRIVATE void
+do_rx_SBCW(int k) {
+  if (rx[k].anr.flag) lmsr_adapt(rx[k].anr.gen);
+  if (rx[k].anf.flag) lmsr_adapt(rx[k].anf.gen);
+}
+
+PRIVATE void
+do_rx_AM(int k) { AMDemod(rx[k].am.gen); }
+
+PRIVATE void
+do_rx_FM(int k) { FMDemod(rx[k].fm.gen); }
+
+PRIVATE void
+do_rx_DRM(int k) {}
+
+PRIVATE void
+do_rx_SPEC(int k) {
+  memcpy(CXBbase(rx[k].buf.o),
+	 CXBbase(rx[k].buf.i),
+	 sizeof(COMPLEX) * CXBhave(rx[k].buf.i));
+  if (rx[k].agc.flag) DigitalAgc(rx[k].agc.gen, rx[k].tick);
+}
+
+PRIVATE void
+do_rx_NIL(int k) {
+  int i, n = min(CXBhave(rx[k].buf.i), uni.buflen);
+  for (i = 0; i < n; i++) CXBdata(rx[k].buf.o, i) = cxzero;
+}
+
+/* overall dispatch for RX processing */
+
+PRIVATE void
+do_rx(int k) {
+  do_rx_pre(k);
+  switch (rx[k].mode) {
+  case USB:
+  case LSB:
+  case CWU:
+  case CWL:
+  case DSB:  do_rx_SBCW(k); break;
+  case AM:
+  case SAM:  do_rx_AM(k); break;
+  case FMN:  do_rx_FM(k);   break;
+  case DRM:  do_rx_DRM(k);  break;
+  case SPEC:
+    default: do_rx_SPEC(k); break;
+  }
+  do_rx_post(k);
+}  
+
+//==============================================================
+/* TX processing */
+
+/* pre-condition for (nearly) all TX modes */
+
+PRIVATE void
+do_tx_pre(void) {
+
+if (tx.scl.pre.flag) {
+int i, n = CXBhave(tx.buf.i);
+    for (i = 0; i < n; i++)
+      CXBdata(tx.buf.i, i) = Cmplx(CXBreal(tx.buf.i, i) * tx.scl.pre.val, 0.0);
+  }
+
+  correctIQ(tx.buf.i, tx.iqfix);
+
+  if (tx.spr.flag) SpeechProcessor(tx.spr.gen);
+
+  if (tx.tick == 0) reset_OvSv(tx.filt.ovsv);
+  filter_OvSv(tx.filt.ovsv);
+}
+
+PRIVATE void
+do_tx_post(void) {
+  CXBhave(tx.buf.o) = CXBhave(tx.buf.i);
+
+  if (tx.agc.flag) DigitalAgc(tx.agc.gen, tx.tick);
+
+  // meter modulated signal
+
+  do_tx_meter(tx.buf.o, TXMETER_POST_MOD);
+
+  if (tx.scl.post.flag) {
+    int i, n = CXBhave(tx.buf.o);
+    for (i = 0; i < n; i++)
+      CXBdata(tx.buf.o, i) = Cscl(CXBdata(tx.buf.o, i), tx.scl.post.val);
+  }
+
+  if (uni.spec.flag)
+    do_tx_spectrum(tx.buf.o);
+
+  if (tx.osc.gen->Frequency != 0.0) {
+    int i;
+    ComplexOSC(tx.osc.gen);
+    for (i = 0; i < CXBhave(tx.buf.o); i++)
+      CXBdata(tx.buf.o, i) = Cmul(CXBdata(tx.buf.o, i), OSCCdata(tx.osc.gen, i));
+  }
+}
+
+/* modulator processing */
+
+PRIVATE void
+do_tx_SBCW(void) {
+  int i, n = min(CXBhave(tx.buf.o), uni.buflen); 
+
+  if ((tx.norm = CXBnorm(tx.buf.o)) > 0.0)
+    for (i = 0; i < n; i++) {
+      tx.scl.dc = Cadd(Cscl(tx.scl.dc, 0.99),
+		       Cscl(CXBdata(tx.buf.o, i), -0.01));
+      CXBdata(tx.buf.o, i) = Cadd(CXBdata(tx.buf.o, i), tx.scl.dc);
+    }
+}
+
+PRIVATE void
+do_tx_AM(void) {
+  int i, n = min(CXBhave(tx.buf.o), uni.buflen); 
+
+  if ((tx.norm = CXBnorm(tx.buf.o)) > 0.0)
+    for (i = 0; i < n; i++) { 
+      tx.scl.dc = Cadd(Cscl(tx.scl.dc, 0.999),
+		       Cscl(CXBdata(tx.buf.o, i), -0.001));
+      CXBreal(tx.buf.o, i) =
+	0.49995 + 0.49995 * (CXBreal(tx.buf.o, i) - tx.scl.dc.re);
+      CXBimag(tx.buf.o, i) = 0.0;
+    }
+}
+
+PRIVATE void
+do_tx_FM(void) {
+  int i, n = min(CXBhave(tx.buf.o), uni.buflen);
+  if ((tx.norm = CXBnorm(tx.buf.o)) > 0.0)
+    for (i = 0; i < n; i++) {
+      tx.scl.dc = Cadd(Cscl(tx.scl.dc, 0.999),
+		       Cscl(CXBdata(tx.buf.o, i), 0.001));
+      tx.osc.phase += (CXBreal(tx.buf.o, i) - tx.scl.dc.re) * CvtMod2Freq;
+      if (tx.osc.phase >= TWOPI) tx.osc.phase -= TWOPI;
+      if (tx.osc.phase < 0.0) tx.osc.phase += TWOPI;
+      CXBdata(tx.buf.o, i) =
+	Cscl(Cmplx(cos(tx.osc.phase), sin(tx.osc.phase)), 0.99999);
+    }
+}
+
+PRIVATE void
+do_tx_NIL(void) {
+  int i, n = min(CXBhave(tx.buf.i), uni.buflen);
+  for (i = 0; i < n; i++) CXBdata(tx.buf.o, i) = cxzero;
+}
+
+/* general TX processing dispatch */
+
+PRIVATE void
+do_tx(void) {
+  do_tx_pre();
+  switch (tx.mode) {
+  case USB:
+  case LSB:
+  case CWU:
+  case CWL:
+  case DSB:  do_tx_SBCW(); break;
+  case AM:
+  case SAM:  do_tx_AM();   break;
+  case FMN:  do_tx_FM();   break;
+  case DRM:
+  case SPEC:
+    default: do_tx_NIL(); break;
+  }
+  do_tx_post();
+}
+
+//========================================================================
+/* overall buffer processing;
+   come here when there are buffers to work on */
+
+void
+process_samples(float *bufl, float *bufr,
+		float *auxl, float *auxr,
+		int n) {
+  int i, k;
+  
+  switch (uni.mode.trx) {
+    
+  case RX:
+    
+    // make copies of the input for all receivers
+    for (k = 0; k < uni.multirx.nrx; k++)
+      if (uni.multirx.act[k]) {
+	for (i = 0; i < n; i++)
+	  CXBimag(rx[k].buf.i, i) = bufl[i], CXBreal(rx[k].buf.i, i) = bufr[i];
+	CXBhave(rx[k].buf.i) = n;
+      }
+
+    // prepare buffers for mixing
+    memset((char *) bufl, 0, n * sizeof(float));
+    memset((char *) bufr, 0, n * sizeof(float));
+
+    // run all receivers
+    for (k = 0; k < uni.multirx.nrx; k++)
+      if (uni.multirx.act[k]) {
+	do_rx(k), rx[k].tick++;
+	// mix
+	for (i = 0; i < n; i++)
+          bufl[i] += (float)CXBimag(rx[k].buf.o, i),
+	  bufr[i] += (float)CXBreal(rx[k].buf.o, i);
+	CXBhave(rx[k].buf.o) = n;
+      }
+
+    // late mixing of aux buffers
+    if (uni.mix.rx.flag)
+      for (i = 0; i < n; i++)
+	bufl[i] += (float)(auxl[i] * uni.mix.rx.gain),
+	bufr[i] += (float)(auxr[i] * uni.mix.rx.gain);
+
+    break;
+
+  case TX:
+
+    // early mixing of aux buffers
+    if (uni.mix.tx.flag)
+      for (i = 0; i < n; i++)
+	bufl[i] += (float)(auxl[i] * uni.mix.tx.gain),
+	bufr[i] += (float)(auxr[i] * uni.mix.tx.gain);
+
+    for (i = 0; i < n; i++)
+      CXBimag(tx.buf.i, i) = bufl[i], CXBreal(tx.buf.i, i) = bufr[i];
+    CXBhave(tx.buf.i) = n;
+
+    do_tx(), tx.tick++;
+
+    for (i = 0; i < n; i++)
+      bufl[i] = (float) CXBimag(tx.buf.o, i), bufr[i] = (float) CXBreal(tx.buf.o, i);
+    CXBhave(tx.buf.o) = n;
+
+    break;
+  }
+
+  uni.tick++;
+}
diff --git a/jDttSP/win/sdrexport.c b/jDttSP/win/sdrexport.c
new file mode 100644
index 0000000..4213ef3
--- /dev/null
+++ b/jDttSP/win/sdrexport.c
@@ -0,0 +1,39 @@
+/* sdrexport.c
+
+This file is part of a program that implements a Software-Defined Radio.
+
+Copyright (C) 2004 by Frank Brickle, AB2KT and Bob McGwier, N4HY
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+The authors can be reached by email at
+
+ab2kt@arrl.net
+or
+rwmcgwier@comcast.net
+
+or by paper mail at
+
+The DTTS Microwave Society
+6 Kathleen Place
+Bridgewater, NJ 08807
+*/
+
+#include <common.h>
+
+struct _uni uni;
+struct _rx rx[MAXRX];
+struct _tx tx;
+struct _top top;
diff --git a/jDttSP/win/winmain.c b/jDttSP/win/winmain.c
new file mode 100644
index 0000000..28ed4df
--- /dev/null
+++ b/jDttSP/win/winmain.c
@@ -0,0 +1,820 @@
+/* main.c
+
+This file is part of a program that implements a Software-Defined Radio.
+
+Copyright (C) 2004-5 by Frank Brickle, AB2KT and Bob McGwier, N4HY
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+The authors can be reached by email at
+
+ab2kt@arrl.net
+or
+rwmcgwier@comcast.net
+
+or by paper mail at
+
+The DTTS Microwave Society
+6 Kathleen Place
+Bridgewater, NJ 08807
+*/
+
+#include <common.h>
+
+/////////////////////////////////////////////////////////////////////////
+
+// Windows SHTUFF
+
+PRIVATE CRITICAL_SECTION csobj;
+PRIVATE CRITICAL_SECTION cs_updobj;
+PRIVATE LPCRITICAL_SECTION cs;
+PRIVATE LPCRITICAL_SECTION cs_upd;
+PRIVATE BOOLEAN IC = FALSE;
+
+// elementary defaults
+struct _loc loc;
+
+/////////////////////////////////////////////////////////////////////////
+// most of what little we know here about the inner loop,
+// functionally speaking
+
+extern void reset_meters(void);
+extern void reset_spectrum(void);
+extern void reset_counters(void);
+extern void process_samples(float *, float *, float *, float *, int);
+extern void setup_workspace(void);
+extern void destroy_workspace(void);
+
+//========================================================================
+
+PRIVATE void
+spectrum_thread(void)
+{
+  DWORD NumBytesWritten;
+  while (top.running) {
+    sem_wait(&top.sync.pws.sem);
+    compute_spectrum(&uni.spec);
+    WriteFile(top.meas.spec.fd, (LPVOID) & uni.spec.label,
+	      sizeof(int), &NumBytesWritten, NULL);
+    WriteFile(top.meas.spec.fd, (LPVOID) uni.spec.output,
+	      sizeof(float) * uni.spec.size, &NumBytesWritten, NULL);
+  }
+  pthread_exit(0);
+}
+
+/*PRIVATE void
+scope_thread(void) {
+  DWORD NumBytesWritten;
+  while (top.running) {
+    sem_wait(&top.sync.scope.sem);
+    compute_spectrum(&uni.spec);
+	WriteFile(top.meas.scope.fd,(LPVOID)&uni.spec.label,
+		sizeof(int),&NumBytesWritten,NULL);
+	WriteFile(top.meas.scope.fd,(LPVOID)uni.spec.accum,
+		sizeof(float)*uni.spec.size,&NumBytesWritten,NULL);
+  }
+  pthread_exit(0);
+} */
+
+PRIVATE void
+meter_thread(void)
+{
+  DWORD NumBytesWritten;
+  while (top.running) {
+    sem_wait(&top.sync.mtr.sem);
+    WriteFile(top.meas.mtr.fd, (LPVOID) & uni.meter.label, sizeof(int),
+	      &NumBytesWritten, NULL);
+    WriteFile(top.meas.mtr.fd, (LPVOID) & uni.meter.snap.rx,
+	      sizeof(REAL) * MAXRX * RXMETERPTS, &NumBytesWritten, NULL);
+    WriteFile(top.meas.mtr.fd, (LPVOID) & uni.meter.snap.tx,
+	      sizeof(REAL) * TXMETERPTS, &NumBytesWritten, NULL);
+  }
+  pthread_exit(0);
+}
+
+//========================================================================
+
+PRIVATE void
+monitor_thread(void)
+{
+  while (top.running) {
+    sem_wait(&top.sync.mon.sem);
+    /* If there is anything that needs monitoring, do it here */
+    fprintf(stderr,
+	    "@@@ mon [%d]: cb = %d rbi = %d rbo = %d xr = %d\n",
+	    uni.tick,
+	    top.jack.blow.cb,
+	    top.jack.blow.rb.i, top.jack.blow.rb.o, top.jack.blow.xr);
+    memset((char *) &top.jack.blow, 0, sizeof(top.jack.blow));
+  }
+  pthread_exit(0);
+
+}
+
+//========================================================================
+
+PRIVATE void
+process_updates_thread(void)
+{
+
+  while (top.running) {
+    DWORD NumBytesRead;
+    pthread_testcancel();
+    while (ReadFile(top.parm.fd, top.parm.buff, 256, &NumBytesRead, NULL)) {
+      fprintf(stderr, "Update Bytes:%lu Msg:%s\n", NumBytesRead,
+	      top.parm.buff), fflush(stderr);
+      if (NumBytesRead != 0)
+	do_update(top.parm.buff, top.verbose ? stderr : 0);
+    }
+  }
+  pthread_exit(0);
+}
+
+//========================================================================
+
+
+PRIVATE void
+gethold(void)
+{
+  EnterCriticalSection(cs);
+  if (ringb_write_space(top.jack.ring.o.l)
+      < top.hold.size.bytes) {
+    // pathology
+    ringb_reset(top.jack.ring.o.l);
+    ringb_reset(top.jack.ring.o.r);
+    top.jack.blow.rb.o++;
+  }
+  ringb_write(top.jack.ring.o.l,
+	      (char *) top.hold.buf.l, top.hold.size.bytes);
+  ringb_write(top.jack.ring.o.r,
+	      (char *) top.hold.buf.r, top.hold.size.bytes);
+  if (ringb_read_space(top.jack.ring.i.l)
+      < top.hold.size.bytes) {
+    // pathology
+    ringb_reset(top.jack.ring.i.l);
+    ringb_reset(top.jack.ring.i.r);
+    memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
+    memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
+    ringb_reset(top.jack.auxr.i.l);
+    ringb_reset(top.jack.auxr.i.r);
+    memset((char *) top.hold.aux.l, 0, top.hold.size.bytes);
+    memset((char *) top.hold.aux.r, 0, top.hold.size.bytes);
+    top.jack.blow.rb.i++;
+  } else {
+    ringb_read(top.jack.ring.i.l,
+	       (char *) top.hold.buf.l, top.hold.size.bytes);
+    ringb_read(top.jack.ring.i.r,
+	       (char *) top.hold.buf.r, top.hold.size.bytes);
+    ringb_read(top.jack.auxr.i.l,
+	       (char *) top.hold.aux.l, top.hold.size.bytes);
+    ringb_read(top.jack.auxr.i.r,
+	       (char *) top.hold.aux.r, top.hold.size.bytes);
+  }
+  LeaveCriticalSection(cs);
+}
+
+PRIVATE BOOLEAN
+canhold(void)
+{
+  BOOLEAN answer;
+  EnterCriticalSection(cs);
+  answer = (ringb_read_space(top.jack.ring.i.l) >= top.hold.size.bytes);
+  LeaveCriticalSection(cs);
+  return answer;
+}
+
+
+//------------------------------------------------------------------------
+
+PRIVATE void
+run_mute(void)
+{
+  memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
+  memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
+  memset((char *) top.hold.aux.l, 0, top.hold.size.bytes);
+  memset((char *) top.hold.aux.r, 0, top.hold.size.bytes);
+  uni.tick++;
+}
+
+PRIVATE void
+run_pass(void)
+{
+  uni.tick++;
+}
+
+PRIVATE void
+run_play(void)
+{
+  process_samples(top.hold.buf.l, top.hold.buf.r,
+		  top.hold.aux.l, top.hold.aux.r, top.hold.size.frames);
+}
+
+// NB do not set RUN_SWCH directly via setRunState;
+// use setSWCH instead
+
+PRIVATE void
+run_swch(void)
+{
+  if (top.swch.bfct.have == 0) {
+    // first time
+    // apply ramp down
+    int i, m = top.swch.fade, n = top.swch.tail;
+    for (i = 0; i < m; i++) {
+      float w = (float) 1.0 - (float) i / m;
+      top.hold.buf.l[i] *= w, top.hold.buf.r[i] *= w;
+    }
+    memset((char *) (top.hold.buf.l + m), 0, n);
+    memset((char *) (top.hold.buf.r + m), 0, n);
+    top.swch.bfct.have++;
+  } else if (top.swch.bfct.have < top.swch.bfct.want) {
+    // in medias res
+    memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
+    memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
+    top.swch.bfct.have++;
+  } else {
+    // last time
+    // apply ramp up
+    int i, m = top.swch.fade, n = top.swch.tail;
+    for (i = 0; i < m; i++) {
+      float w = (float) i / m;
+      top.hold.buf.l[i] *= w, top.hold.buf.r[i] *= w;
+    }
+    uni.mode.trx = top.swch.trx.next;
+    switch (uni.mode.trx) {
+      int i;
+    case TX:
+      tx.agc.gen->over = tx.tick + 3;
+      break;
+    case RX:
+      for (i = 0; i < uni.multirx.nrx; i++)
+	rx[i].agc.gen->over = rx[i].tick + 3;
+      break;
+    }
+
+    top.state = top.swch.run.last;
+    top.swch.bfct.want = top.swch.bfct.have = 0;
+
+    ringb_reset(top.jack.ring.o.l);
+    ringb_reset(top.jack.ring.o.r);
+    ringb_clear(top.jack.ring.o.l, top.hold.size.bytes);
+    ringb_clear(top.jack.ring.o.r, top.hold.size.bytes);
+
+    reset_meters();
+    reset_spectrum();
+    reset_counters();
+  }
+
+  process_samples(top.hold.buf.l, top.hold.buf.r,
+		  top.hold.aux.l, top.hold.aux.r, top.hold.size.frames);
+}
+
+//========================================================================
+
+
+
+DttSP_EXP void
+audio_callback(float *input_l, float *input_r, float *output_l,
+	       float *output_r, int nframes)
+{
+  size_t nbytes = sizeof(float) * nframes;
+
+
+  EnterCriticalSection(cs);
+
+
+  if (ringb_read_space(top.jack.ring.o.l) >= nbytes) {
+    ringb_read(top.jack.ring.o.l, (char *) output_l, nbytes);
+    ringb_read(top.jack.ring.o.r, (char *) output_r, nbytes);
+  } else {			// rb pathology
+    memset((char *) output_l, 0, nbytes);
+    memset((char *) output_r, 0, nbytes);
+    ringb_restart(top.jack.ring.o.l, nbytes);
+    ringb_restart(top.jack.ring.o.r, nbytes);
+    top.jack.blow.rb.o++;
+  }
+
+  // input: copy from port to ring
+  if (ringb_write_space(top.jack.ring.i.l) >= nbytes) {
+    ringb_write(top.jack.ring.i.l, (char *) input_l, nbytes);
+    ringb_write(top.jack.ring.i.r, (char *) input_r, nbytes);
+    ringb_write(top.jack.auxr.i.l, (char *) input_l, nbytes);
+    ringb_write(top.jack.auxr.i.r, (char *) input_r, nbytes);
+  } else {			// rb pathology
+    ringb_restart(top.jack.ring.i.l, nbytes);
+    ringb_restart(top.jack.ring.i.r, nbytes);
+    ringb_restart(top.jack.auxr.i.l, nbytes);
+    ringb_restart(top.jack.auxr.i.r, nbytes);
+    top.jack.blow.rb.i++;
+  }
+  LeaveCriticalSection(cs);
+  // if enough accumulated in ring, fire dsp
+  if (ringb_read_space(top.jack.ring.i.l) >= top.hold.size.bytes)
+    sem_post(&top.sync.buf.sem);
+
+  // check for blowups
+  if ((top.jack.blow.cb > 0) ||
+      (top.jack.blow.rb.i > 0) || (top.jack.blow.rb.o > 0))
+    sem_post(&top.sync.mon.sem);
+}
+
+//========================================================================
+
+DttSP_EXP void
+process_samples_thread(void)
+{
+  while (top.running) {
+    sem_wait(&top.sync.buf.sem);
+    do {
+      gethold();
+      sem_wait(&top.sync.upd.sem);
+      switch (top.state) {
+      case RUN_MUTE:
+	run_mute();
+	break;
+      case RUN_PASS:
+	run_pass();
+	break;
+      case RUN_PLAY:
+	run_play();
+	break;
+      case RUN_SWCH:
+	run_swch();
+	break;
+      }
+      sem_post(&top.sync.upd.sem);
+    } while (canhold());
+  }
+}
+
+
+void
+closeup(void)
+{
+  top.running = FALSE;
+  Sleep(50);
+  safefree((char *) top.jack.ring.o.r);
+  safefree((char *) top.jack.ring.o.l);
+  safefree((char *) top.jack.ring.i.r);
+  safefree((char *) top.jack.ring.i.l);
+  safefree((char *) top.jack.auxr.i.l);
+  safefree((char *) top.jack.auxr.i.r);
+  safefree((char *) top.jack.auxr.o.l);
+  safefree((char *) top.jack.auxr.o.r);
+
+  CloseHandle(top.parm.fp);
+  DisconnectNamedPipe(top.parm.fd);
+  CloseHandle(top.parm.fd);
+
+
+  if (uni.meter.flag) {
+    CloseHandle(top.meas.mtr.fp);
+    DisconnectNamedPipe(top.meas.mtr.fd);
+    CloseHandle(top.meas.mtr.fd);
+  };
+
+  if (uni.spec.flag) {
+    CloseHandle(top.meas.spec.fp);
+    DisconnectNamedPipe(top.meas.spec.fd);
+    CloseHandle(top.meas.spec.fd);
+  };
+  destroy_workspace();
+}
+
+//........................................................................
+
+PRIVATE void
+setup_switching(void)
+{
+  top.swch.fade = (int) (0.1 * uni.buflen + 0.5);
+  top.swch.tail = (top.hold.size.frames - top.swch.fade) * sizeof(float);
+}
+
+PRIVATE void
+setup_local_audio(void)
+{
+  top.hold.size.frames = uni.buflen;
+  top.hold.size.bytes = top.hold.size.frames * sizeof(float);
+  top.hold.buf.l = (float *) safealloc(top.hold.size.frames, sizeof(float),
+				       "main hold buffer left");
+  top.hold.buf.r = (float *) safealloc(top.hold.size.frames, sizeof(float),
+				       "main hold buffer right");
+  top.hold.aux.l = (float *) safealloc(top.hold.size.frames, sizeof(float),
+				       "aux hold buffer left");
+  top.hold.aux.r = (float *) safealloc(top.hold.size.frames, sizeof(float),
+				       "aux hold buffer right");
+}
+
+#include <lmerr.h>
+
+PRIVATE void
+DisplayErrorText(DWORD dwLastError)
+{
+  HMODULE hModule = NULL;	// default to system source
+  LPSTR MessageBuffer;
+  DWORD dwBufferLength;
+
+  DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
+    FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM;
+
+  //
+  // If dwLastError is in the network range, 
+  //  load the message source.
+  //
+
+  if (dwLastError >= NERR_BASE && dwLastError <= MAX_NERR) {
+    hModule = LoadLibraryEx(TEXT("netmsg.dll"),
+			    NULL, LOAD_LIBRARY_AS_DATAFILE);
+
+    if (hModule != NULL)
+      dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
+  }
+  //
+  // Call FormatMessage() to allow for message 
+  //  text to be acquired from the system 
+  //  or from the supplied module handle.
+  //
+
+  if (dwBufferLength = FormatMessageA(dwFormatFlags, hModule,	// module to get message from (NULL == system)
+				      dwLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),	// default language
+				      (LPSTR) & MessageBuffer, 0, NULL)) {
+    DWORD dwBytesWritten;
+
+    //
+    // Output message string on stderr.
+    //
+    WriteFile(GetStdHandle(STD_ERROR_HANDLE),
+	      MessageBuffer, dwBufferLength, &dwBytesWritten, NULL);
+
+    //
+    // Free the buffer allocated by the system.
+    //
+    LocalFree(MessageBuffer);
+  }
+  //
+  // If we loaded a message source, unload it.
+  //
+  if (hModule != NULL)
+    FreeLibrary(hModule);
+}
+
+
+
+PRIVATE sem_t setup_update_sem;
+
+PRIVATE void
+setup_update_server()
+{
+
+  if (INVALID_HANDLE_VALUE == (top.parm.fd = CreateNamedPipe(top.parm.path,
+							     PIPE_ACCESS_INBOUND,
+							     PIPE_WAIT |
+							     PIPE_TYPE_MESSAGE
+							     |
+							     PIPE_READMODE_MESSAGE,
+							     PIPE_UNLIMITED_INSTANCES,
+							     512, 512,
+							     INFINITE,
+							     NULL))) {
+    fprintf(stderr, "Update server pipe setup failed:\n"), fflush(stderr);
+    DisplayErrorText(GetLastError());
+  }
+//  fprintf(stderr,"Update NamedPipe made\n"),fflush(stderr);
+  sem_post(&setup_update_sem);
+  if (ConnectNamedPipe(top.parm.fd, NULL)) {
+//      fprintf(stderr,"Connected the server to the Update pipe\n"),fflush(stderr);
+  } else {
+    fprintf(stderr, "Connected the server to the Update pipe failed\n"),
+      fflush(stderr);
+    DisplayErrorText(GetLastError());
+  }
+  pthread_exit(0);
+}
+
+
+PRIVATE void
+setup_update_client()
+{
+//      fprintf(stderr,"Looking for the Update server\n"),fflush(stderr);
+  WaitNamedPipe(top.parm.path, INFINITE);
+//      fprintf(stderr,"Found the Update server\n"),fflush(stderr);
+  if (INVALID_HANDLE_VALUE == (top.parm.fp = CreateFile(top.parm.path,
+							GENERIC_WRITE, 0,
+							NULL, OPEN_EXISTING,
+							FILE_ATTRIBUTE_NORMAL,
+							NULL))) {
+    fprintf(stderr, "The Update Client Open Failed\n"), fflush(stderr);
+    DisplayErrorText(GetLastError());
+  }
+  sem_post(&setup_update_sem);
+/*	{
+		DWORD numwritten;
+		WriteFile(top.parm.fp,"test",5,&numwritten,NULL);
+		fprintf(stderr,"Number written to server: %lu\n",numwritten),fflush(stderr);
+	}*/
+  pthread_exit(0);
+}
+
+PRIVATE void
+setup_meter_server()
+{
+  top.meas.mtr.fd = CreateNamedPipe(top.meas.mtr.path,
+				    PIPE_ACCESS_OUTBOUND,
+				    PIPE_WAIT | PIPE_TYPE_MESSAGE |
+				    PIPE_READMODE_MESSAGE,
+				    PIPE_UNLIMITED_INSTANCES, 512, 512,
+				    INFINITE, NULL);
+//  fprintf(stderr,"meter handle = %08X\n",(DWORD)top.meas.mtr.fd),fflush(stderr);
+  if (top.meas.mtr.fd == INVALID_HANDLE_VALUE) {
+    fprintf(stderr, "Meter server pipe setup failed:\n"), fflush(stderr);
+    DisplayErrorText(GetLastError());
+  } else {
+//        fprintf(stderr,"Meter Pipe Connect succeeded\n"),fflush(stderr);
+    sem_post(&setup_update_sem);
+    if (ConnectNamedPipe(top.meas.mtr.fd, NULL)) {
+//          fprintf(stderr,"Connected the Meter Pooch\n"),fflush(stderr);
+    } else {
+      fprintf(stderr, "Meter Pipe Connect failed\n"), fflush(stderr);
+      DisplayErrorText(GetLastError());
+    }
+  }
+  pthread_exit(0);
+}
+
+PRIVATE void
+setup_meter_client()
+{
+//      fprintf(stderr,"Looking for the meter server\n"),fflush(stderr);
+  if (WaitNamedPipe(top.meas.mtr.path, INFINITE)) {
+//        fprintf(stderr,"Found the Meter server\n"),fflush(stderr);
+    if (INVALID_HANDLE_VALUE ==
+	(top.meas.mtr.fp =
+	 CreateFile(top.meas.mtr.path, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+		    FILE_ATTRIBUTE_NORMAL, NULL))) {
+      fprintf(stderr, "The Meter Client Open Failed\n"), fflush(stderr);
+      DisplayErrorText(GetLastError());
+    } else {
+//                      fprintf(stderr,"The Meter Client Open Succeeded\n"),fflush(stderr);
+    }
+  } else {
+    fprintf(stderr, "Wait for meter pipe failed: Error message %d\n",
+	    GetLastError()), fflush(stderr);
+  }
+  sem_post(&setup_update_sem);
+  pthread_exit(0);
+}
+
+PRIVATE void
+setup_spec_server()
+{
+
+  if (INVALID_HANDLE_VALUE ==
+      (top.meas.spec.fd =
+       CreateNamedPipe(top.meas.spec.path, PIPE_ACCESS_OUTBOUND,
+		       PIPE_WAIT | PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
+		       PIPE_UNLIMITED_INSTANCES, 32768, 32768, INFINITE,
+		       NULL))) {
+    fprintf(stderr, "Spectrum pipe create failed\n"), fflush(stderr);
+    DisplayErrorText(GetLastError());
+  } else {
+//        fprintf(stderr,"Spectrum Pipe %s Create succeeded\n",top.meas.spec.path),fflush(stderr);
+    sem_post(&setup_update_sem);
+    if (ConnectNamedPipe(top.meas.spec.fd, NULL)) {
+//          fprintf(stderr,"Connected to the Spectrum Pipe\n"),fflush(stderr);
+    } else {
+      fprintf(stderr, "Spectrum pipe connect failed\n"), fflush(stderr);
+      DisplayErrorText(GetLastError());
+    }
+  }
+  pthread_exit(0);
+}
+
+PRIVATE void
+setup_spec_client()
+{
+//      fprintf(stderr,"Looking for the spectrum server\n"),fflush(stderr);
+  if (WaitNamedPipe(top.meas.spec.path, INFINITE)) {
+//              fprintf(stderr,"Found the server\n"),fflush(stderr);
+    if (INVALID_HANDLE_VALUE ==
+	(top.meas.spec.fp =
+	 CreateFile(top.meas.spec.path, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+		    FILE_ATTRIBUTE_NORMAL, NULL))) {
+      fprintf(stderr, "The Spectrum Client Open Failed\n"), fflush(stderr);
+      DisplayErrorText(GetLastError());
+    } else {
+//                      fprintf(stderr,"The Spectrum Client Open Succeeded\n");
+//                      fprintf(stderr,"Spec Read handle = %08X\n",(DWORD)top.meas.spec.fp),fflush(stderr);
+    }
+  } else {
+    fprintf(stderr, "Wait for spec pipe failed\n"), fflush(stderr);
+    DisplayErrorText(GetLastError());
+  }
+  sem_post(&setup_update_sem);
+  pthread_exit(0);
+}
+PRIVATE pthread_t id1, id2, id3, id4, id5, id6;
+PRIVATE void
+setup_updates(void)
+{
+
+  char mesg[16384] = "TEST TEST METER\n";
+//  DWORD NumBytes;
+  top.parm.path = loc.path.parm;
+  sem_init(&setup_update_sem, 0, 0);
+
+
+  if (uni.meter.flag) {
+    top.meas.mtr.path = loc.path.meter;
+  }
+  if (uni.spec.flag) {
+    top.meas.spec.path = loc.path.spec;
+  }
+
+  // Do this STUPID stuff to make use of the Named Pipe Mechanism in Windows
+  // For the update server
+
+
+  pthread_create(&id1, NULL, (void *) setup_update_server, NULL);
+  sem_wait(&setup_update_sem);
+  pthread_create(&id2, NULL, (void *) setup_update_client, NULL);
+  sem_wait(&setup_update_sem);
+  if (uni.meter.flag) {
+    pthread_create(&id3, NULL, (void *) setup_meter_server, NULL);
+    sem_wait(&setup_update_sem);
+    pthread_create(&id4, NULL, (void *) setup_meter_client, NULL);
+    sem_wait(&setup_update_sem);
+/*	  if (WriteFile(top.meas.mtr.fd,mesg,strlen(mesg)+1,&NumBytes,NULL))
+	  {
+		  fprintf(stderr,"Meter Pipe write succeeded and wrote %lu bytes\n",NumBytes),fflush(stderr);
+	  } else {
+		  fprintf(stderr,"Meter Pipe write failed\n"),fflush(stderr);
+		  DisplayErrorText(GetLastError());
+	  }
+	  if (ReadFile(top.meas.mtr.fp,mesg,256,&NumBytes,NULL))
+	  {
+		  fprintf(stderr,"Meter Pipe read succeeded and %lu bytes read\n",NumBytes),fflush(stderr);
+		  fprintf(stderr,"Meter message %s",mesg),fflush(stderr);
+	  } else {
+		  fprintf(stderr,"Meter Pipe read failed\n"),fflush(stderr);
+		  DisplayErrorText(GetLastError());
+	  }*/
+
+  }
+
+  if (uni.spec.flag) {
+    memset(mesg, 0, 16384);
+    pthread_create(&id5, NULL, (void *) setup_spec_server, NULL);
+    sem_wait(&setup_update_sem);
+    pthread_create(&id6, NULL, (void *) setup_spec_client, NULL);
+    sem_wait(&setup_update_sem);
+    Sleep(0);
+/*	  if (WriteFile(top.meas.spec.fd,mesg,16384,&NumBytes,NULL))
+	  {
+		  fprintf(stderr,"Spec Pipe write succeeded and wrote %lu bytes\n",NumBytes),fflush(stderr);
+	  } else {
+		  fprintf(stderr,"Spec Pipe write failed\n"),fflush(stderr);
+		  DisplayErrorText(GetLastError());
+	  }
+ 	  fprintf(stderr,"Spec Read handle(2) = %08X\n",(DWORD)top.meas.spec.fp),fflush(stderr);
+	  if (ReadFile(top.meas.spec.fp,mesg,16384,&NumBytes,NULL))
+	  {
+		  fprintf(stderr,"Spec Pipe read succeeded and %lu bytes read\n",NumBytes),fflush(stderr);
+	  } else {
+		  fprintf(stderr,"Spec Pipe read failed\n"),fflush(stderr);
+		  DisplayErrorText(GetLastError());
+	  } */
+  }
+  sem_destroy(&setup_update_sem);
+}
+PRIVATE void
+setup_system_audio(void)
+{
+  size_t ringsize;
+  void *usemem;
+  sprintf(top.jack.name, "sdr-%d", top.pid);
+  top.jack.size = uni.buflen;
+  ringsize = top.hold.size.bytes * loc.mult.ring + sizeof(ringb_t);
+  usemem = safealloc(ringsize, 1, "Ring Input Left");
+  top.jack.ring.i.l =
+    ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
+
+  usemem = safealloc(ringsize, 1, "Ring Input Right");
+  top.jack.ring.i.r =
+    ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
+
+  usemem = safealloc(ringsize, 1, "Ring Output Left");
+  top.jack.ring.o.l =
+    ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
+
+  usemem = safealloc(ringsize, 1, "Ring Output Right");
+  top.jack.ring.o.r =
+    ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
+
+  usemem = safealloc(ringsize, 1, "Ring Input Left Auxiliary");
+  top.jack.auxr.i.l =
+    ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
+
+  usemem = safealloc(ringsize, 1, "Ring Input Right Auxiliary");
+  top.jack.auxr.i.r =
+    ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
+
+  usemem = safealloc(ringsize, 1, "Ring Output Left Auxiliary");
+  top.jack.auxr.o.l =
+    ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
+
+  usemem = safealloc(ringsize, 1, "Ring Output Right Auxiliary");
+  top.jack.auxr.o.r =
+    ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
+
+  ringb_clear(top.jack.ring.o.l, top.jack.size * sizeof(float));
+  ringb_clear(top.jack.ring.o.r, top.jack.size * sizeof(float));
+  ringb_clear(top.jack.auxr.o.l, top.jack.size * sizeof(float));
+  ringb_clear(top.jack.auxr.o.r, top.jack.size * sizeof(float));
+}
+
+PRIVATE void
+setup_threading(void)
+{
+  sem_init(&top.sync.upd.sem, 0, 0);
+  pthread_create(&top.thrd.upd.id, NULL, (void *) process_updates_thread,
+		 NULL);
+  sem_init(&top.sync.buf.sem, 0, 0);
+  pthread_create(&top.thrd.trx.id, NULL, (void *) process_samples_thread,
+		 NULL);
+  sem_init(&top.sync.mon.sem, 0, 0);
+  pthread_create(&top.thrd.mon.id, NULL, (void *) monitor_thread, NULL);
+  if (uni.meter.flag) {
+    sem_init(&top.sync.mtr.sem, 0, 0);
+    pthread_create(&top.thrd.mtr.id, NULL, (void *) meter_thread, NULL);
+  }
+  if (uni.spec.flag) {
+    sem_init(&top.sync.pws.sem, 0, 0);
+    pthread_create(&top.thrd.pws.id, NULL, (void *) spectrum_thread, NULL);
+  }
+  cs = &csobj;
+  InitializeCriticalSection(cs);
+}
+
+//========================================================================
+// hard defaults, then environment
+
+PRIVATE void
+setup_defaults(void)
+{
+  loc.name[0] = 0;		// no default name for jack client
+  strcpy(loc.path.rcfile, RCBASE);
+  strcpy(loc.path.parm, PARMPATH);
+  strcpy(loc.path.meter, METERPATH);
+  strcpy(loc.path.spec, SPECPATH);
+  strcpy(loc.path.wisdom, WISDOMPATH);
+  loc.def.rate = DEFRATE;
+  loc.def.size = DEFSIZE;
+  loc.def.nrx = MAXRX;
+  loc.def.mode = DEFMODE;
+  loc.def.spec = DEFSPEC;
+  loc.mult.ring = RINGMULT;
+}
+
+//========================================================================
+void
+setup()
+{
+
+
+  top.pid = GetCurrentThreadId();
+  top.uid = 0L;
+  top.start_tv = now_tv();
+  top.running = TRUE;
+  top.verbose = FALSE;
+  top.state = RUN_PLAY;
+
+  setup_defaults();
+  top.verbose = FALSE;
+  uni.meter.flag = TRUE;
+  uni.spec.flag = TRUE;
+
+  setup_workspace();
+  setup_updates();
+
+  setup_local_audio();
+  setup_system_audio();
+
+  setup_threading();
+  setup_switching();
+  uni.spec.flag = TRUE;
+  uni.spec.type = SPEC_POST_FILT;
+  uni.spec.scale = SPEC_PWR;
+  uni.spec.rxk = 0;
+
+}
diff --git a/jDttSP/win/winmain.c~ b/jDttSP/win/winmain.c~
new file mode 100644
index 0000000..9832178
--- /dev/null
+++ b/jDttSP/win/winmain.c~
@@ -0,0 +1,803 @@
+/* main.c
+
+This file is part of a program that implements a Software-Defined Radio.
+
+Copyright (C) 2004-5 by Frank Brickle, AB2KT and Bob McGwier, N4HY
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+The authors can be reached by email at
+
+ab2kt@arrl.net
+or
+rwmcgwier@comcast.net
+
+or by paper mail at
+
+The DTTS Microwave Society
+6 Kathleen Place
+Bridgewater, NJ 08807
+*/  
+  
+#include <common.h>
+  
+/////////////////////////////////////////////////////////////////////////
+
+// Windows SHTUFF
+
+PRIVATE CRITICAL_SECTION	csobj;
+PRIVATE CRITICAL_SECTION cs_updobj;
+PRIVATE LPCRITICAL_SECTION  cs;
+PRIVATE LPCRITICAL_SECTION cs_upd;
+PRIVATE BOOLEAN IC=FALSE;
+
+// elementary defaults
+struct _loc  loc;  
+
+/////////////////////////////////////////////////////////////////////////
+// most of what little we know here about the inner loop,
+// functionally speaking
+
+extern void reset_meters(void);
+extern void reset_spectrum(void);
+extern void reset_counters(void);
+extern void process_samples(float *, float *, float *, float *, int);
+extern void setup_workspace(void);
+extern void destroy_workspace(void);
+
+//========================================================================
+
+PRIVATE void
+spectrum_thread(void) {
+  DWORD NumBytesWritten;
+  while (top.running) {
+    sem_wait(&top.sync.pws.sem);
+    compute_spectrum(&uni.spec);
+	WriteFile(top.meas.spec.fd,(LPVOID)&uni.spec.label,
+		sizeof(int),&NumBytesWritten,NULL);
+	WriteFile(top.meas.spec.fd,(LPVOID)uni.spec.output,
+		sizeof(float)*uni.spec.size,&NumBytesWritten,NULL);
+  }
+  pthread_exit(0);
+}
+
+/*PRIVATE void
+scope_thread(void) {
+  DWORD NumBytesWritten;
+  while (top.running) {
+    sem_wait(&top.sync.scope.sem);
+    compute_spectrum(&uni.spec);
+	WriteFile(top.meas.scope.fd,(LPVOID)&uni.spec.label,
+		sizeof(int),&NumBytesWritten,NULL);
+	WriteFile(top.meas.scope.fd,(LPVOID)uni.spec.accum,
+		sizeof(float)*uni.spec.size,&NumBytesWritten,NULL);
+  }
+  pthread_exit(0);
+} */
+
+PRIVATE void
+meter_thread(void) {
+  DWORD NumBytesWritten;
+  while (top.running) {
+    sem_wait(&top.sync.mtr.sem);
+	WriteFile(top.meas.mtr.fd,(LPVOID)&uni.meter.label, sizeof(int),&NumBytesWritten,NULL);
+	WriteFile(top.meas.mtr.fd,(LPVOID)&uni.meter.snap.rx,sizeof(REAL)*MAXRX * RXMETERPTS,&NumBytesWritten,NULL);
+	WriteFile(top.meas.mtr.fd,(LPVOID)&uni.meter.snap.tx,sizeof(REAL)*TXMETERPTS,&NumBytesWritten,NULL);
+  }
+  pthread_exit(0);   
+}
+
+//========================================================================
+
+PRIVATE void
+monitor_thread(void) {
+  while (top.running) {
+    sem_wait(&top.sync.mon.sem);
+   /* If there is anything that needs monitoring, do it here */
+    fprintf(stderr,
+	    "@@@ mon [%d]: cb = %d rbi = %d rbo = %d xr = %d\n",
+	    uni.tick,
+	    top.jack.blow.cb,
+	    top.jack.blow.rb.i,
+	    top.jack.blow.rb.o,
+	    top.jack.blow.xr);
+    memset((char *) &top.jack.blow, 0, sizeof(top.jack.blow));
+  }
+  pthread_exit(0); 
+  
+}
+
+//========================================================================
+
+PRIVATE void 
+process_updates_thread(void) {
+  
+  while (top.running) {
+	  DWORD NumBytesRead;
+	  pthread_testcancel();
+	  while (ReadFile(top.parm.fd,top.parm.buff,256,&NumBytesRead,NULL))
+	  {
+		  fprintf(stderr,"Update Bytes:%lu Msg:%s\n",NumBytesRead,top.parm.buff),fflush(stderr);
+		  if (NumBytesRead != 0) do_update(top.parm.buff, top.verbose ? stderr : 0);
+	  }
+  }
+  pthread_exit(0);
+}
+
+//========================================================================
+
+
+PRIVATE void
+gethold(void) {
+  EnterCriticalSection(cs);
+  if (ringb_write_space(top.jack.ring.o.l)
+      < top.hold.size.bytes) {
+    // pathology
+    ringb_reset(top.jack.ring.o.l);
+    ringb_reset(top.jack.ring.o.r);
+    top.jack.blow.rb.o++;
+  }
+  ringb_write(top.jack.ring.o.l,
+			(char *) top.hold.buf.l,
+			top.hold.size.bytes);
+  ringb_write(top.jack.ring.o.r,
+			(char *) top.hold.buf.r,
+			top.hold.size.bytes);
+  if (ringb_read_space(top.jack.ring.i.l)
+      < top.hold.size.bytes) {
+    // pathology
+    ringb_reset(top.jack.ring.i.l);
+    ringb_reset(top.jack.ring.i.r);
+    memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
+    memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
+    ringb_reset(top.jack.auxr.i.l);
+    ringb_reset(top.jack.auxr.i.r);
+    memset((char *) top.hold.aux.l, 0, top.hold.size.bytes);
+    memset((char *) top.hold.aux.r, 0, top.hold.size.bytes);
+    top.jack.blow.rb.i++;
+  } else {
+    ringb_read(top.jack.ring.i.l,
+			 (char *) top.hold.buf.l,
+			 top.hold.size.bytes);
+    ringb_read(top.jack.ring.i.r,
+			 (char *) top.hold.buf.r,
+			 top.hold.size.bytes);
+    ringb_read(top.jack.auxr.i.l,
+			 (char *) top.hold.aux.l,
+			 top.hold.size.bytes);
+    ringb_read(top.jack.auxr.i.r,
+			 (char *) top.hold.aux.r,
+			 top.hold.size.bytes);
+  }
+  LeaveCriticalSection(cs);
+}
+
+PRIVATE BOOLEAN
+canhold(void) {
+  BOOLEAN answer;
+  EnterCriticalSection(cs);
+  answer = (ringb_read_space(top.jack.ring.i.l) >= top.hold.size.bytes);
+  LeaveCriticalSection(cs);
+  return answer;
+}
+
+
+//------------------------------------------------------------------------
+
+PRIVATE void 
+run_mute(void) {
+  memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
+  memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
+  memset((char *) top.hold.aux.l, 0, top.hold.size.bytes);
+  memset((char *) top.hold.aux.r, 0, top.hold.size.bytes);
+  uni.tick++;
+}
+
+PRIVATE void 
+run_pass(void) { uni.tick++; }
+
+PRIVATE void 
+run_play(void) {
+  process_samples(top.hold.buf.l, top.hold.buf.r,
+		  top.hold.aux.l, top.hold.aux.r,
+		  top.hold.size.frames);
+} 
+
+// NB do not set RUN_SWCH directly via setRunState;
+// use setSWCH instead
+
+PRIVATE void 
+run_swch(void) {
+  if (top.swch.bfct.have == 0) {
+    // first time
+    // apply ramp down
+    int i, m = top.swch.fade, n = top.swch.tail;
+    for (i = 0; i < m; i++) {
+      float w = (float) 1.0 - (float) i / m;
+      top.hold.buf.l[i] *= w, top.hold.buf.r[i] *= w;
+    }
+    memset((char *) (top.hold.buf.l + m), 0, n);
+    memset((char *) (top.hold.buf.r + m), 0, n);
+    top.swch.bfct.have++;
+  } else if (top.swch.bfct.have < top.swch.bfct.want) {
+    // in medias res
+    memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
+    memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
+    top.swch.bfct.have++;
+  } else {
+    // last time
+    // apply ramp up
+    int i, m = top.swch.fade, n = top.swch.tail;
+    for (i = 0; i < m; i++) {
+      float w = (float) i / m;
+      top.hold.buf.l[i] *= w, top.hold.buf.r[i] *= w;
+    }
+    uni.mode.trx = top.swch.trx.next;
+	switch (uni.mode.trx) {
+		int i;
+		case TX:
+			tx.agc.gen->over = tx.tick + 3;
+			break;
+		case RX:
+			for(i=0;i<uni.multirx.nrx;i++) rx[i].agc.gen->over = rx[i].tick + 3;
+			break;
+	}
+
+    top.state = top.swch.run.last;
+    top.swch.bfct.want = top.swch.bfct.have = 0;
+
+    ringb_reset(top.jack.ring.o.l);
+    ringb_reset(top.jack.ring.o.r);
+    ringb_clear(top.jack.ring.o.l,top.hold.size.bytes);
+    ringb_clear(top.jack.ring.o.r,top.hold.size.bytes);
+
+    reset_meters();
+    reset_spectrum();
+    reset_counters();
+  }
+
+  process_samples(top.hold.buf.l, top.hold.buf.r,
+		  top.hold.aux.l, top.hold.aux.r,
+		  top.hold.size.frames);
+} 
+
+//========================================================================
+
+
+
+DttSP_EXP void
+audio_callback(float *input_l, float *input_r, float *output_l, float *output_r,int nframes) {
+  size_t nbytes = sizeof(float)*nframes;
+
+
+  EnterCriticalSection(cs);
+
+
+    if (ringb_read_space(top.jack.ring.o.l) >= nbytes) {
+      ringb_read(top.jack.ring.o.l, (char *) output_l, nbytes);
+      ringb_read(top.jack.ring.o.r, (char *) output_r, nbytes);
+    } else { // rb pathology
+      memset((char *) output_l, 0, nbytes);
+      memset((char *) output_r, 0, nbytes);
+      ringb_restart(top.jack.ring.o.l, nbytes);
+      ringb_restart(top.jack.ring.o.r, nbytes);
+      top.jack.blow.rb.o++;
+    }
+    
+    // input: copy from port to ring
+    if (ringb_write_space(top.jack.ring.i.l) >= nbytes) {
+      ringb_write(top.jack.ring.i.l, (char *) input_l, nbytes);
+      ringb_write(top.jack.ring.i.r, (char *) input_r, nbytes);
+      ringb_write(top.jack.auxr.i.l, (char *) input_l, nbytes);
+      ringb_write(top.jack.auxr.i.r, (char *) input_r, nbytes);
+    } else { // rb pathology
+      ringb_restart(top.jack.ring.i.l, nbytes);
+      ringb_restart(top.jack.ring.i.r, nbytes);
+      ringb_restart(top.jack.auxr.i.l, nbytes);
+      ringb_restart(top.jack.auxr.i.r, nbytes);
+      top.jack.blow.rb.i++;
+    }
+  LeaveCriticalSection(cs);
+  // if enough accumulated in ring, fire dsp
+  if (ringb_read_space(top.jack.ring.i.l) >= top.hold.size.bytes)
+    sem_post(&top.sync.buf.sem);
+
+  // check for blowups
+  if ((top.jack.blow.cb > 0) ||
+      (top.jack.blow.rb.i > 0) ||
+      (top.jack.blow.rb.o > 0))
+    sem_post(&top.sync.mon.sem);
+}
+
+//========================================================================
+
+DttSP_EXP void 
+process_samples_thread(void) {
+  while (top.running) {
+    sem_wait(&top.sync.buf.sem);
+    do {
+      gethold();
+      sem_wait(&top.sync.upd.sem);
+      switch (top.state) {
+      case RUN_MUTE: run_mute(); break;
+      case RUN_PASS: run_pass(); break;
+      case RUN_PLAY: run_play(); break;
+      case RUN_SWCH: run_swch(); break;
+      }
+      sem_post(&top.sync.upd.sem);
+    } while (canhold());
+  }
+}
+
+
+void 
+closeup(void) {
+  top.running = FALSE;
+  Sleep(50);
+  safefree((char *)top.jack.ring.o.r);
+  safefree((char *)top.jack.ring.o.l);
+  safefree((char *)top.jack.ring.i.r);
+  safefree((char *)top.jack.ring.i.l);
+  safefree((char *)top.jack.auxr.i.l);
+  safefree((char *)top.jack.auxr.i.r);
+  safefree((char *)top.jack.auxr.o.l);
+  safefree((char *)top.jack.auxr.o.r);
+
+   CloseHandle(top.parm.fp); 
+   DisconnectNamedPipe(top.parm.fd); 
+   CloseHandle(top.parm.fd); 
+
+
+  if (uni.meter.flag) {
+    CloseHandle(top.meas.mtr.fp); 
+	DisconnectNamedPipe(top.meas.mtr.fd); 
+	CloseHandle(top.meas.mtr.fd); 
+  };
+  
+  if (uni.spec.flag) {
+	  CloseHandle(top.meas.spec.fp); 
+	  DisconnectNamedPipe(top.meas.spec.fd); 
+	  CloseHandle(top.meas.spec.fd); 
+  };
+  destroy_workspace();
+}
+
+//........................................................................
+
+PRIVATE void 
+setup_switching(void) {
+  top.swch.fade = (int) (0.1 * uni.buflen + 0.5);
+  top.swch.tail = (top.hold.size.frames - top.swch.fade) * sizeof(float);
+}
+
+PRIVATE void 
+setup_local_audio(void) {
+  top.hold.size.frames = uni.buflen;
+  top.hold.size.bytes = top.hold.size.frames * sizeof(float);
+  top.hold.buf.l = (float *) safealloc(top.hold.size.frames, sizeof(float),
+				       "main hold buffer left");
+  top.hold.buf.r = (float *) safealloc(top.hold.size.frames, sizeof(float),
+				       "main hold buffer right");
+  top.hold.aux.l = (float *) safealloc(top.hold.size.frames, sizeof(float),
+				       "aux hold buffer left");
+  top.hold.aux.r = (float *) safealloc(top.hold.size.frames, sizeof(float),
+				       "aux hold buffer right");
+}
+
+#include <lmerr.h>
+
+PRIVATE void
+DisplayErrorText(DWORD dwLastError)
+{
+    HMODULE hModule = NULL; // default to system source
+    LPSTR MessageBuffer;
+    DWORD dwBufferLength;
+
+    DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
+        FORMAT_MESSAGE_IGNORE_INSERTS |
+        FORMAT_MESSAGE_FROM_SYSTEM ;
+
+    //
+    // If dwLastError is in the network range, 
+    //  load the message source.
+    //
+
+    if(dwLastError >= NERR_BASE && dwLastError <= MAX_NERR) {
+        hModule = LoadLibraryEx(
+            TEXT("netmsg.dll"),
+            NULL,
+            LOAD_LIBRARY_AS_DATAFILE
+            );
+
+        if(hModule != NULL)
+            dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
+    }
+
+    //
+    // Call FormatMessage() to allow for message 
+    //  text to be acquired from the system 
+    //  or from the supplied module handle.
+    //
+
+    if(dwBufferLength = FormatMessageA(
+        dwFormatFlags,
+        hModule, // module to get message from (NULL == system)
+        dwLastError,
+        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
+        (LPSTR) &MessageBuffer,
+        0,
+        NULL
+        ))
+    {
+        DWORD dwBytesWritten;
+
+        //
+        // Output message string on stderr.
+        //
+        WriteFile(
+            GetStdHandle(STD_ERROR_HANDLE),
+            MessageBuffer,
+            dwBufferLength,
+            &dwBytesWritten,
+            NULL
+            );
+
+        //
+        // Free the buffer allocated by the system.
+        //
+        LocalFree(MessageBuffer);
+    }
+
+    //
+    // If we loaded a message source, unload it.
+    //
+    if(hModule != NULL)
+        FreeLibrary(hModule);
+}
+
+
+
+PRIVATE sem_t setup_update_sem;
+
+PRIVATE void setup_update_server()
+{
+
+  if (INVALID_HANDLE_VALUE == (top.parm.fd = CreateNamedPipe(top.parm.path,
+			PIPE_ACCESS_INBOUND,
+			PIPE_WAIT|PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE,
+			PIPE_UNLIMITED_INSTANCES,
+			512,
+			512,
+			INFINITE,
+			NULL)))
+  {
+ 	  fprintf(stderr,"Update server pipe setup failed:\n"),fflush(stderr);
+	  DisplayErrorText(GetLastError());
+ }
+//  fprintf(stderr,"Update NamedPipe made\n"),fflush(stderr);
+  sem_post(&setup_update_sem);
+  if (ConnectNamedPipe(top.parm.fd,NULL))
+  {
+//	fprintf(stderr,"Connected the server to the Update pipe\n"),fflush(stderr);
+  } else {
+	  fprintf(stderr,"Connected the server to the Update pipe failed\n"),fflush(stderr);
+	  DisplayErrorText(GetLastError());
+  }
+	pthread_exit(0);
+}
+
+
+PRIVATE void setup_update_client()
+{
+//	fprintf(stderr,"Looking for the Update server\n"),fflush(stderr);
+	WaitNamedPipe(top.parm.path,INFINITE);
+//	fprintf(stderr,"Found the Update server\n"),fflush(stderr);
+	if (INVALID_HANDLE_VALUE == (top.parm.fp = CreateFile(top.parm.path,
+	GENERIC_WRITE, 0, NULL,
+    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)))
+	{
+		fprintf(stderr,"The Update Client Open Failed\n"),fflush(stderr);
+		DisplayErrorText(GetLastError());
+	}
+	sem_post(&setup_update_sem);
+/*	{
+		DWORD numwritten;
+		WriteFile(top.parm.fp,"test",5,&numwritten,NULL);
+		fprintf(stderr,"Number written to server: %lu\n",numwritten),fflush(stderr);
+	}*/
+	pthread_exit(0);
+}
+
+PRIVATE void setup_meter_server()
+{
+  top.meas.mtr.fd = CreateNamedPipe(top.meas.mtr.path,
+			PIPE_ACCESS_OUTBOUND,
+			PIPE_WAIT|PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE,
+			PIPE_UNLIMITED_INSTANCES,
+			512,
+			512,
+			INFINITE,
+			NULL);
+//  fprintf(stderr,"meter handle = %08X\n",(DWORD)top.meas.mtr.fd),fflush(stderr);
+  if (top.meas.mtr.fd == INVALID_HANDLE_VALUE)
+  { 
+	  fprintf(stderr,"Meter server pipe setup failed:\n"),fflush(stderr);
+	  DisplayErrorText(GetLastError());
+  } else {
+//	  fprintf(stderr,"Meter Pipe Connect succeeded\n"),fflush(stderr);
+	  sem_post(&setup_update_sem);
+	  if (ConnectNamedPipe(top.meas.mtr.fd,NULL)) {
+//          fprintf(stderr,"Connected the Meter Pooch\n"),fflush(stderr);
+	  } else {
+		  fprintf(stderr,"Meter Pipe Connect failed\n"),fflush(stderr);
+		  DisplayErrorText(GetLastError());
+	  }
+  }
+  pthread_exit(0);
+}
+
+PRIVATE void setup_meter_client()
+{
+//	fprintf(stderr,"Looking for the meter server\n"),fflush(stderr);
+	if (WaitNamedPipe(top.meas.mtr.path,INFINITE)) {
+//        fprintf(stderr,"Found the Meter server\n"),fflush(stderr);
+		if (INVALID_HANDLE_VALUE == (top.meas.mtr.fp = CreateFile(top.meas.mtr.path,
+			GENERIC_READ, 0, NULL,
+			OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)))
+		{
+			fprintf(stderr,"The Meter Client Open Failed\n"),fflush(stderr);
+			DisplayErrorText(GetLastError());
+		} else {
+//			fprintf(stderr,"The Meter Client Open Succeeded\n"),fflush(stderr);
+		}
+	} else {
+		fprintf(stderr,"Wait for meter pipe failed: Error message %d\n",GetLastError()),fflush(stderr);
+	}
+	sem_post(&setup_update_sem);
+	pthread_exit(0);
+}
+
+PRIVATE void setup_spec_server()
+{
+
+  if (INVALID_HANDLE_VALUE == (top.meas.spec.fd = CreateNamedPipe(top.meas.spec.path,
+			PIPE_ACCESS_OUTBOUND,
+			PIPE_WAIT|PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE,
+			PIPE_UNLIMITED_INSTANCES,
+			32768,
+			32768,
+			INFINITE,
+			NULL)))
+  {
+	  fprintf(stderr,"Spectrum pipe create failed\n"),fflush(stderr);
+	  DisplayErrorText(GetLastError());
+  } else {
+//	  fprintf(stderr,"Spectrum Pipe %s Create succeeded\n",top.meas.spec.path),fflush(stderr);
+	  sem_post(&setup_update_sem);
+	  if (ConnectNamedPipe(top.meas.spec.fd,NULL))
+	  {
+//          fprintf(stderr,"Connected to the Spectrum Pipe\n"),fflush(stderr);
+	  } else {
+		  fprintf(stderr,"Spectrum pipe connect failed\n"),fflush(stderr);
+		  DisplayErrorText(GetLastError());
+	  }
+  }
+  pthread_exit(0);
+}
+
+PRIVATE void setup_spec_client()
+{
+//	fprintf(stderr,"Looking for the spectrum server\n"),fflush(stderr);
+	if (WaitNamedPipe(top.meas.spec.path,INFINITE)) {
+//		fprintf(stderr,"Found the server\n"),fflush(stderr);
+		if (INVALID_HANDLE_VALUE == (top.meas.spec.fp = CreateFile(top.meas.spec.path,
+			GENERIC_READ, 0, NULL,
+			OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)))
+		{
+			fprintf(stderr,"The Spectrum Client Open Failed\n"),fflush(stderr);
+			DisplayErrorText(GetLastError());
+		} else {
+//			fprintf(stderr,"The Spectrum Client Open Succeeded\n");
+//			fprintf(stderr,"Spec Read handle = %08X\n",(DWORD)top.meas.spec.fp),fflush(stderr);
+		}
+	} else {
+		fprintf(stderr,"Wait for spec pipe failed\n"),fflush(stderr);
+		DisplayErrorText(GetLastError());
+	}
+	sem_post(&setup_update_sem);
+	pthread_exit(0);
+}
+PRIVATE pthread_t id1,id2,id3,id4,id5,id6;
+PRIVATE void 
+setup_updates(void) {
+
+  char mesg[16384]="TEST TEST METER\n";
+//  DWORD NumBytes;
+  top.parm.path = loc.path.parm;
+  sem_init(&setup_update_sem, 0, 0);
+  
+
+  if (uni.meter.flag) {
+    top.meas.mtr.path = loc.path.meter;
+  }
+  if (uni.spec.flag) {
+    top.meas.spec.path = loc.path.spec;
+  }
+
+   
+	  // Do this STUPID stuff to make use of the Named Pipe Mechanism in Windows
+	  // For the update server
+
+	
+  pthread_create(&id1, NULL, (void *) setup_update_server, NULL);
+  sem_wait(&setup_update_sem);
+  pthread_create(&id2, NULL, (void *) setup_update_client, NULL);
+  sem_wait(&setup_update_sem);
+  if (uni.meter.flag) {
+	  pthread_create(&id3, NULL, (void *) setup_meter_server, NULL);
+	  sem_wait(&setup_update_sem);
+	  pthread_create(&id4, NULL, (void *) setup_meter_client, NULL);
+	  sem_wait(&setup_update_sem);
+/*	  if (WriteFile(top.meas.mtr.fd,mesg,strlen(mesg)+1,&NumBytes,NULL))
+	  {
+		  fprintf(stderr,"Meter Pipe write succeeded and wrote %lu bytes\n",NumBytes),fflush(stderr);
+	  } else {
+		  fprintf(stderr,"Meter Pipe write failed\n"),fflush(stderr);
+		  DisplayErrorText(GetLastError());
+	  }
+	  if (ReadFile(top.meas.mtr.fp,mesg,256,&NumBytes,NULL))
+	  {
+		  fprintf(stderr,"Meter Pipe read succeeded and %lu bytes read\n",NumBytes),fflush(stderr);
+		  fprintf(stderr,"Meter message %s",mesg),fflush(stderr);
+	  } else {
+		  fprintf(stderr,"Meter Pipe read failed\n"),fflush(stderr);
+		  DisplayErrorText(GetLastError());
+	  }*/
+	  
+  }
+ 
+  if (uni.spec.flag) {
+	  memset(mesg,0,16384);
+	  pthread_create(&id5, NULL, (void *) setup_spec_server, NULL);
+	  sem_wait(&setup_update_sem);
+	  pthread_create(&id6, NULL, (void *) setup_spec_client, NULL);
+	  sem_wait(&setup_update_sem);
+	  Sleep(0);
+/*	  if (WriteFile(top.meas.spec.fd,mesg,16384,&NumBytes,NULL))
+	  {
+		  fprintf(stderr,"Spec Pipe write succeeded and wrote %lu bytes\n",NumBytes),fflush(stderr);
+	  } else {
+		  fprintf(stderr,"Spec Pipe write failed\n"),fflush(stderr);
+		  DisplayErrorText(GetLastError());
+	  }
+ 	  fprintf(stderr,"Spec Read handle(2) = %08X\n",(DWORD)top.meas.spec.fp),fflush(stderr);
+	  if (ReadFile(top.meas.spec.fp,mesg,16384,&NumBytes,NULL))
+	  {
+		  fprintf(stderr,"Spec Pipe read succeeded and %lu bytes read\n",NumBytes),fflush(stderr);
+	  } else {
+		  fprintf(stderr,"Spec Pipe read failed\n"),fflush(stderr);
+		  DisplayErrorText(GetLastError());
+	  } */
+  }
+  sem_destroy(&setup_update_sem);
+}
+PRIVATE void 
+setup_system_audio(void) {
+	size_t ringsize;
+	void *usemem;
+	sprintf(top.jack.name, "sdr-%d", top.pid);
+	top.jack.size = uni.buflen;
+	ringsize = top.hold.size.bytes * loc.mult.ring+sizeof(ringb_t);
+	usemem = safealloc(ringsize,1,"Ring Input Left");
+	top.jack.ring.i.l = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
+
+	usemem = safealloc(ringsize,1,"Ring Input Right");
+	top.jack.ring.i.r = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
+
+	usemem = safealloc(ringsize,1,"Ring Output Left");
+	top.jack.ring.o.l = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
+
+	usemem = safealloc(ringsize,1,"Ring Output Right");
+	top.jack.ring.o.r = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
+
+	usemem = safealloc(ringsize,1,"Ring Input Left Auxiliary");
+	top.jack.auxr.i.l = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
+
+	usemem = safealloc(ringsize,1,"Ring Input Right Auxiliary");
+	top.jack.auxr.i.r = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
+
+	usemem = safealloc(ringsize,1,"Ring Output Left Auxiliary");
+	top.jack.auxr.o.l = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
+
+	usemem = safealloc(ringsize,1,"Ring Output Right Auxiliary");
+	top.jack.auxr.o.r = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
+
+	ringb_clear(top.jack.ring.o.l, top.jack.size * sizeof(float));
+	ringb_clear(top.jack.ring.o.r, top.jack.size * sizeof(float));
+	ringb_clear(top.jack.auxr.o.l, top.jack.size * sizeof(float));
+	ringb_clear(top.jack.auxr.o.r, top.jack.size * sizeof(float));
+}
+
+PRIVATE void 
+setup_threading(void) {
+  sem_init(&top.sync.upd.sem, 0, 0);
+  pthread_create(&top.thrd.upd.id, NULL, (void *) process_updates_thread, NULL);
+  sem_init(&top.sync.buf.sem, 0, 0);
+  pthread_create(&top.thrd.trx.id, NULL, (void *) process_samples_thread, NULL);
+  sem_init(&top.sync.mon.sem, 0, 0);
+  pthread_create(&top.thrd.mon.id, NULL, (void *) monitor_thread, NULL);
+  if (uni.meter.flag) {
+    sem_init(&top.sync.mtr.sem, 0, 0);
+    pthread_create(&top.thrd.mtr.id, NULL, (void *) meter_thread, NULL);
+  }
+  if (uni.spec.flag) {
+    sem_init(&top.sync.pws.sem, 0, 0);
+    pthread_create(&top.thrd.pws.id, NULL, (void *) spectrum_thread, NULL);
+  }
+  cs = &csobj;
+  InitializeCriticalSection(cs);
+} 
+
+//========================================================================
+// hard defaults, then environment
+
+PRIVATE void
+setup_defaults(void) {
+  loc.name[0] = 0; // no default name for jack client
+  strcpy(loc.path.rcfile, RCBASE);
+  strcpy(loc.path.parm, PARMPATH);
+  strcpy(loc.path.meter, METERPATH);
+  strcpy(loc.path.spec, SPECPATH);
+  strcpy(loc.path.wisdom, WISDOMPATH);
+  loc.def.rate = DEFRATE;
+  loc.def.size = DEFSIZE;
+  loc.def.nrx = MAXRX;
+  loc.def.mode = DEFMODE;
+  loc.def.spec = DEFSPEC;
+  loc.mult.ring = RINGMULT;
+}
+
+//========================================================================
+void 
+setup() {
+
+
+  top.pid = GetCurrentThreadId();
+  top.uid = 0L;
+  top.start_tv = now_tv();
+  top.running = TRUE;
+  top.verbose = FALSE;
+  top.state = RUN_PLAY;
+
+  setup_defaults();
+  top.verbose = FALSE;
+  uni.meter.flag = TRUE;
+  uni.spec.flag = TRUE;
+
+  setup_workspace();
+  setup_updates();
+
+  setup_local_audio();
+  setup_system_audio();
+
+  setup_threading();
+  setup_switching();
+    uni.spec.flag = TRUE;
+  	uni.spec.type  = SPEC_POST_FILT;
+	uni.spec.scale = SPEC_PWR;
+	uni.spec.rxk = 0;
+
+}
+