Skip to content

Commit

Permalink
Merge pull request #1 from thewsoftware/initial
Browse files Browse the repository at this point in the history
Initial commit
  • Loading branch information
thewsoftware committed Apr 7, 2024
2 parents ce1ff8a + b4c00ce commit d01fc26
Show file tree
Hide file tree
Showing 13 changed files with 766 additions and 1 deletion.
37 changes: 37 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Log files
*.log

# Unit test reports
TEST*.xml

# Generated by MacOS
.DS_Store

# Generated by Windows
Thumbs.db

# Applications
*.app
*.exe
*.war

# Large media files
*.mp4
*.tiff
*.avi
*.flv
*.mov
*.wmv

# Visual Studio files
*.suo
*.user
*.crt
*.key
.vs
bin
obj
packages

launchSettings.json
*.pubxml
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# sdrfc
SDR Frequency Converter
# SDR# <-> SDR++ Frequency Converter
A lightweight command line tool to convert frequency lists berween SDR# and SDR++ formats,

37 changes: 37 additions & 0 deletions SDR.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34018.315
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sdrfc", "Sdrfc\Sdrfc.csproj", "{57F3A0F6-1A82-44B1-8E89-D82A3F876C51}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SdrfcLib", "SdrfcLib\SdrfcLib.csproj", "{9FCD8316-90DB-4036-BF53-35B3A362A902}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{962791A7-50E6-4CEC-A3F8-E7F318548CFD}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
README.md = README.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{57F3A0F6-1A82-44B1-8E89-D82A3F876C51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{57F3A0F6-1A82-44B1-8E89-D82A3F876C51}.Debug|Any CPU.Build.0 = Debug|Any CPU
{57F3A0F6-1A82-44B1-8E89-D82A3F876C51}.Release|Any CPU.ActiveCfg = Release|Any CPU
{57F3A0F6-1A82-44B1-8E89-D82A3F876C51}.Release|Any CPU.Build.0 = Release|Any CPU
{9FCD8316-90DB-4036-BF53-35B3A362A902}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FCD8316-90DB-4036-BF53-35B3A362A902}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FCD8316-90DB-4036-BF53-35B3A362A902}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FCD8316-90DB-4036-BF53-35B3A362A902}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {32F0CEFF-7821-4226-B014-34B6F8B991CC}
EndGlobalSection
EndGlobal
191 changes: 191 additions & 0 deletions Sdrfc/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
using FrequencyManagerCommon;
using FrequencyManagerCommon.Helpers;
using FrequencyManagerCommon.Models;

namespace SdrSharpToSdrPlusPlus;

class Program
{
static void Main(string[] args)
{
const string SdrppDefaultFileName = "frequency_manager_config.json";
const string SdrsharpDefaultFileName = "frequencies.xml";
const string CopyOption = "-c";
const string MergeOption = "-m";

if (args.Length == 0)
{
Help();
}
else
{
var option = isOption(args[0]) ? args[0].Trim().ToLower() : CopyOption;

if (!CopyOption.Equals(option) && !MergeOption.Equals(option))
{
Help();
}

var inputFileName = !isOption(args[0]) ? args[0] : args[1];

var outputFileName = !isOption(args[0])
? (args.Length > 1 ? args[1] : null)
: (args.Length > 2 ? args[2] : null);

using (var sdrpp = new SdrPlusPlusHelper())
using (var sdrsharp = new SdrSharpHelper())
{
var inputFileExt = Path.GetExtension(inputFileName);

if (".json".Equals(inputFileExt.ToLower()))
{
// convert from sdr++ format to sdr#

if (!File.Exists(inputFileName))
{
ErrorAndExit($"File does not exists; {inputFileName}");
}

var inputChannels = sdrpp.LoadFromFile(inputFileName);

if (inputChannels == null || !inputChannels.Any())
{
ErrorAndExit($"Invalid file format; {inputFileName} is not SDR++ frequency file.");
}

outputFileName = outputFileName?.ToLower() ?? SdrsharpDefaultFileName;

var outputChannels = File.Exists(outputFileName)
? sdrsharp.LoadFromFile(outputFileName)
: new List<Channel>();

try
{
using (var frequencyManager = new FrequencyManager(outputChannels))
{
if (File.Exists(outputFileName) && MergeOption.Equals(option))
{
WriteLine($"Merge {inputFileName.ToLower()} ({inputChannels.Count} channels) into {outputFileName.ToLower()} ({outputChannels.Count} channels).");
WriteLine($"Matching by [group name]+[frequency].");
}
else
{
WriteLine($"Copy {inputFileName.ToLower()} ({inputChannels.Count} channels) into {outputFileName.ToLower()}.");
}

(long updated, long added) = CopyOption.Equals(option)
? frequencyManager.Copy(inputChannels)
: frequencyManager.Merge(inputChannels);

WriteLine($"{updated} channels updated, {added} channels added.");

sdrsharp.SaveToFile(frequencyManager.Channels, outputFileName);
}

Exit();
}
catch (Exception ex )
{
ErrorAndExit(ex.Message);
};
}
else if (".xml".Equals(inputFileExt.ToLower()))
{
// convert from sdr# format to sdr++

if (!File.Exists(inputFileName))
{
ErrorAndExit($"File does not exists; {inputFileName}");
}

var inputChannels = sdrsharp.LoadFromFile(inputFileName);

if (inputChannels == null || !inputChannels.Any())
{
ErrorAndExit($"Invalid file format; {inputFileName} is not SDR# frequency file.");
}

outputFileName = outputFileName?.ToLower() ?? SdrppDefaultFileName;

var outputChannels = File.Exists(outputFileName)
? sdrpp.LoadFromFile(outputFileName)
: new List<Channel>();

try
{
using (var frequencyManager = new FrequencyManager(outputChannels))
{
if (File.Exists(outputFileName) && MergeOption.Equals(option))
{
WriteLine($"Merge {inputFileName.ToLower()} ({inputChannels.Count} channels) into {outputFileName.ToLower()} ({outputChannels.Count} channels).");
WriteLine($"Matching by [group name]+[frequency].");
}
else
{
WriteLine($"Copy {inputFileName.ToLower()} ({inputChannels.Count} channels) into {outputFileName.ToLower()}.");
}

(long updated, long added) = CopyOption.Equals(option)
? frequencyManager.Copy(inputChannels)
: frequencyManager.Merge(inputChannels);

WriteLine($"{updated} channels updated, {added} channels added.");

sdrpp.SaveToFile(frequencyManager.Channels, outputFileName);
}

Exit();
}
catch (Exception ex)
{
ErrorAndExit(ex.Message);
};
}
else
{
Help();
}
}
}
}

static private bool isOption(string text)
{
return text != null && text.Length == 2 && text.StartsWith("-");
}

static private void Help()
{
Console.WriteLine("==============================================================================");
Console.WriteLine($" SDR#/SRD++ frequency file converter https://github.com/thewsoftware ");
Console.WriteLine("==============================================================================");
Console.WriteLine("");
Console.WriteLine("Usage: sdrfc [-option] [drive:][path][inputfilename] [drive:][path][outputfilename]");
Console.WriteLine("");
Console.WriteLine("Options:");
Console.WriteLine("-c\tCopy channels from input file to output file, overwrite the output file (default).");
Console.WriteLine("-m\tMerge channels from input file to output file, save the result into the output file.");
Console.WriteLine("");
Console.WriteLine("Convert frequency channels from one format to another. Auto-detect input and output file formats.");
Console.WriteLine("Create output file if it doesn't exist. If output file does exist and '-m' option is selected");
Console.WriteLine("then frequency channels from input file are merged into the output file and saved.");
Console.WriteLine("");
Exit();
}

static private void Exit()
{
Environment.Exit(0);
}

static private void ErrorAndExit(string message)
{
WriteLine($"Error: {message}");
Environment.Exit(-1);
}

static private void WriteLine(string text)
{
Console.WriteLine($"[SDRFC] {text}");
}
}
22 changes: 22 additions & 0 deletions Sdrfc/Sdrfc.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>1.0.0.1</Version>
<Company>The WSoftware</Company>
<Authors>Yuriy Shcherbakov</Authors>
<Product>SDR Frequency Converter</Product>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\SdrfcLib\SdrfcLib.csproj" />
</ItemGroup>

</Project>
85 changes: 85 additions & 0 deletions SdrfcLib/Extensions/ChannelExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using FrequencyManagerCommon.Models;
using System.Xml.Linq;

namespace FrequencyManagerCommon.Extensions
{
public static class ChannelExtensions
{
public static void MergeTo(this IEnumerable<Channel> src, IEnumerable<Channel> dst)
{
if (src == null || dst == null) return;

foreach (var channel in src)
{
}
}

public static Channel? FindChannel(this IEnumerable<Channel> channels, Channel channel)
{
if (channels == null || channel == null) return null;

return channels.FirstOrDefault(o =>
o.Frequency == channel.Frequency &&
o.GroupName.Equals(channel.GroupName, StringComparison.CurrentCultureIgnoreCase));
}

public static bool SameAs(this Channel src, Channel dst)
{
if (src == null || dst == null) return false;

return src.GroupName.Equals(dst.GroupName, StringComparison.CurrentCultureIgnoreCase) &&
src.Name.Equals(dst.Name, StringComparison.CurrentCultureIgnoreCase) &&
src.Modulation.Equals(dst.Modulation, StringComparison.CurrentCultureIgnoreCase) &&
src.Frequency == dst.Frequency &&
src.Bandwidth == dst.Bandwidth &&
src.Shift == dst.Shift;
}

public static void Update(this Channel dst, Channel src)
{
dst.Name = src.Name;
dst.Modulation = src.Modulation;
dst.Bandwidth = src.Bandwidth;
dst.Shift = src.Shift;
}

public static Channel Clone(this Channel channel)
{
return new Channel
{
IsFavorite = channel.IsFavorite,
Name = channel.Name,
GroupName = channel.GroupName,
Frequency = channel.Frequency,
Bandwidth = channel.Bandwidth,
Shift = channel.Shift,
Modulation = channel.Modulation,
};
}

public static (bool, bool) Merge(this List<Channel> channels, Channel channel)
{
var isUpdated = false;
var isAdded = false;

var existing = channels.FindChannel(channel);

if (existing == null)
{
channels.Add(channel);
isAdded = true;
}
else
{
if (!existing.SameAs(channel))
{
existing.Update(channel);
isUpdated = true;
}
}

return (isUpdated, isAdded);
}

}
}

0 comments on commit d01fc26

Please sign in to comment.