]> git.rkrishnan.org Git - dttsp.git/commitdiff
Upgraded windows alternatives
authordttsp <dttsp>
Sun, 12 Jun 2005 13:49:26 +0000 (13:49 +0000)
committerdttsp <dttsp>
Sun, 12 Jun 2005 13:49:26 +0000 (13:49 +0000)
13 files changed:
jDttSP/win/DttSP.def [new file with mode: 0644]
jDttSP/win/DttSP.sln [new file with mode: 0644]
jDttSP/win/DttSP.vcproj [new file with mode: 0644]
jDttSP/win/DttSPtmp.vcproj [new file with mode: 0644]
jDttSP/win/iosdr.h [new file with mode: 0644]
jDttSP/win/keyb.c [new file with mode: 0644]
jDttSP/win/keyd.c [new file with mode: 0644]
jDttSP/win/keyerio.c [new file with mode: 0644]
jDttSP/win/local.h [new file with mode: 0644]
jDttSP/win/sdr.c [new file with mode: 0644]
jDttSP/win/sdrexport.c [new file with mode: 0644]
jDttSP/win/winmain.c [new file with mode: 0644]
jDttSP/win/winmain.c~ [new file with mode: 0644]

diff --git a/jDttSP/win/DttSP.def b/jDttSP/win/DttSP.def
new file mode 100644 (file)
index 0000000..1450e73
--- /dev/null
@@ -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 (file)
index 0000000..97d2d92
--- /dev/null
@@ -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 (file)
index 0000000..9f7e285
--- /dev/null
@@ -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 (file)
index 0000000..34a6f00
--- /dev/null
@@ -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 (file)
index 0000000..3425566
--- /dev/null
@@ -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 (file)
index 0000000..d01707e
--- /dev/null
@@ -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 (file)
index 0000000..f51dff8
--- /dev/null
@@ -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 (file)
index 0000000..4fe2a61
--- /dev/null
@@ -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 (file)
index 0000000..0c0e2e3
--- /dev/null
@@ -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 (file)
index 0000000..9f52144
--- /dev/null
@@ -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 (file)
index 0000000..4213ef3
--- /dev/null
@@ -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 (file)
index 0000000..28ed4df
--- /dev/null
@@ -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 (file)
index 0000000..9832178
--- /dev/null
@@ -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;
+
+}
+