diff --git a/WhackerLinkConsoleV2.sln b/WhackerLinkConsoleV2.sln
index 149eb69..0309ce5 100644
--- a/WhackerLinkConsoleV2.sln
+++ b/WhackerLinkConsoleV2.sln
@@ -15,35 +15,50 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
NoVocode|Any CPU = NoVocode|Any CPU
+ NoVocode|x64 = NoVocode|x64
NoVocode|x86 = NoVocode|x86
Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5918329A-6374-40E2-874D-445360C89676}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5918329A-6374-40E2-874D-445360C89676}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5918329A-6374-40E2-874D-445360C89676}.Debug|x64.ActiveCfg = AmbeVocode|x64
+ {5918329A-6374-40E2-874D-445360C89676}.Debug|x64.Build.0 = AmbeVocode|x64
{5918329A-6374-40E2-874D-445360C89676}.Debug|x86.ActiveCfg = Debug|x86
{5918329A-6374-40E2-874D-445360C89676}.Debug|x86.Build.0 = Debug|x86
{5918329A-6374-40E2-874D-445360C89676}.NoVocode|Any CPU.ActiveCfg = NoVocode|Any CPU
{5918329A-6374-40E2-874D-445360C89676}.NoVocode|Any CPU.Build.0 = NoVocode|Any CPU
+ {5918329A-6374-40E2-874D-445360C89676}.NoVocode|x64.ActiveCfg = NoVocode|x64
+ {5918329A-6374-40E2-874D-445360C89676}.NoVocode|x64.Build.0 = NoVocode|x64
{5918329A-6374-40E2-874D-445360C89676}.NoVocode|x86.ActiveCfg = NoVocode|x86
{5918329A-6374-40E2-874D-445360C89676}.NoVocode|x86.Build.0 = NoVocode|x86
{5918329A-6374-40E2-874D-445360C89676}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5918329A-6374-40E2-874D-445360C89676}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5918329A-6374-40E2-874D-445360C89676}.Release|x64.ActiveCfg = Release|x64
+ {5918329A-6374-40E2-874D-445360C89676}.Release|x64.Build.0 = Release|x64
{5918329A-6374-40E2-874D-445360C89676}.Release|x86.ActiveCfg = Release|x86
{5918329A-6374-40E2-874D-445360C89676}.Release|x86.Build.0 = Release|x86
{710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.Debug|x64.ActiveCfg = Debug|x64
+ {710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.Debug|x64.Build.0 = Debug|x64
{710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.Debug|x86.ActiveCfg = Debug|Any CPU
{710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.Debug|x86.Build.0 = Debug|Any CPU
{710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.NoVocode|Any CPU.ActiveCfg = Debug|Any CPU
{710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.NoVocode|Any CPU.Build.0 = Debug|Any CPU
+ {710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.NoVocode|x64.ActiveCfg = Debug|x64
+ {710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.NoVocode|x64.Build.0 = Debug|x64
{710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.NoVocode|x86.ActiveCfg = Debug|Any CPU
{710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.NoVocode|x86.Build.0 = Debug|Any CPU
{710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.Release|x64.ActiveCfg = Release|x64
+ {710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.Release|x64.Build.0 = Release|x64
{710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.Release|x86.ActiveCfg = Release|Any CPU
{710D1FA8-2E0D-42CB-9174-FCD9EB7A718F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
diff --git a/WhackerLinkConsoleV2/AudioManager.cs b/WhackerLinkConsoleV2/AudioManager.cs
index 45ee825..7ed87d2 100644
--- a/WhackerLinkConsoleV2/AudioManager.cs
+++ b/WhackerLinkConsoleV2/AudioManager.cs
@@ -24,6 +24,9 @@ using System.Collections.Generic;
namespace WhackerLinkConsoleV2
{
+ ///
+ /// Class for managing
+ ///
public class AudioManager
{
private Dictionary _talkgroupProviders;
diff --git a/WhackerLinkConsoleV2/MainWindow.xaml.cs b/WhackerLinkConsoleV2/MainWindow.xaml.cs
index c8cb50d..62d8a5e 100644
--- a/WhackerLinkConsoleV2/MainWindow.xaml.cs
+++ b/WhackerLinkConsoleV2/MainWindow.xaml.cs
@@ -429,7 +429,7 @@ namespace WhackerLinkConsoleV2
_audioManager.AddTalkgroupStream(cpgChannel.Tgid, combinedAudio);
});
- await Task.Run(async () =>
+ await Task.Run(() =>
{
for (int i = 0; i < totalChunks; i++)
{
@@ -454,12 +454,10 @@ namespace WhackerLinkConsoleV2
};
handler.SendMessage(voicePacket.GetData());
-
- await Task.Delay(20);
}
});
- double totalDurationMs = (toneADuration + toneBDuration) * 1000 + 500;
+ double totalDurationMs = (toneADuration + toneBDuration) * 1000 + 250;
await Task.Delay((int)totalDurationMs);
GRP_VCH_RLS release = new GRP_VCH_RLS
@@ -474,6 +472,7 @@ namespace WhackerLinkConsoleV2
Dispatcher.Invoke(() =>
{
+ //channel.PageState = false; // TODO: Investigate
channel.PageSelectButton.Background = Brushes.Green;
});
}
@@ -487,18 +486,6 @@ namespace WhackerLinkConsoleV2
{
try
{
- try
- {
- using (var player = new SoundPlayer(e.AlertFilePath))
- {
- player.Play();
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show($"Failed to play alert: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
- }
-
foreach (ChannelBox channel in _selectedChannelsManager.GetSelectedChannels())
{
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
@@ -507,37 +494,49 @@ namespace WhackerLinkConsoleV2
if (channel.PageState)
{
- List pcmChunks = new List();
- WaveFileReader waveReader = null;
+ byte[] pcmData;
- using (waveReader = new WaveFileReader(e.AlertFilePath))
+ using (var waveReader = new WaveFileReader(e.AlertFilePath))
{
- if (waveReader.WaveFormat.Encoding != WaveFormatEncoding.Pcm)
+ if (waveReader.WaveFormat.Encoding != WaveFormatEncoding.Pcm ||
+ waveReader.WaveFormat.SampleRate != 8000 ||
+ waveReader.WaveFormat.BitsPerSample != 16 ||
+ waveReader.WaveFormat.Channels != 1)
{
- MessageBox.Show("The alert tone is not in PCM format.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ MessageBox.Show("The alert tone must be PCM 16-bit, Mono, 8000Hz format.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
- byte[] buffer = new byte[1600];
- int bytesRead;
-
- while ((bytesRead = waveReader.Read(buffer, 0, buffer.Length)) > 0)
+ using (MemoryStream ms = new MemoryStream())
{
- if (bytesRead < buffer.Length)
- {
- byte[] finalChunk = new byte[bytesRead];
- Array.Copy(buffer, finalChunk, bytesRead);
- pcmChunks.Add(finalChunk);
- }
- else
- {
- pcmChunks.Add((byte[])buffer.Clone());
- }
+ waveReader.CopyTo(ms);
+ pcmData = ms.ToArray();
}
}
- foreach (var chunk in pcmChunks)
+ int chunkSize = 1600;
+ int totalChunks = (pcmData.Length + chunkSize - 1) / chunkSize;
+
+ if (pcmData.Length % chunkSize != 0)
{
+ byte[] paddedData = new byte[totalChunks * chunkSize];
+ Buffer.BlockCopy(pcmData, 0, paddedData, 0, pcmData.Length);
+ pcmData = paddedData;
+ }
+
+ Task.Factory.StartNew(() =>
+ {
+ _audioManager.AddTalkgroupStream(cpgChannel.Tgid, pcmData);
+ });
+
+ DateTime startTime = DateTime.UtcNow;
+
+ for (int i = 0; i < totalChunks; i++)
+ {
+ int offset = i * chunkSize;
+ byte[] chunk = new byte[chunkSize];
+ Buffer.BlockCopy(pcmData, offset, chunk, 0, chunkSize);
+
AudioPacket voicePacket = new AudioPacket
{
Data = chunk,
@@ -554,10 +553,18 @@ namespace WhackerLinkConsoleV2
handler.SendMessage(voicePacket.GetData());
- int chunkDurationMs = (int)(1600.0 / waveReader.WaveFormat.AverageBytesPerSecond * 1000);
- await Task.Delay(chunkDurationMs);
+ DateTime nextPacketTime = startTime.AddMilliseconds((i + 1) * 100);
+ TimeSpan waitTime = nextPacketTime - DateTime.UtcNow;
+
+ if (waitTime.TotalMilliseconds > 0)
+ {
+ await Task.Delay(waitTime);
+ }
}
+ double totalDurationMs = ((double)pcmData.Length / 16000) * 1000 + 500;
+ await Task.Delay((int)totalDurationMs);
+
GRP_VCH_RLS release = new GRP_VCH_RLS
{
SrcId = system.Rid,
diff --git a/WhackerLinkConsoleV2/SettingsManager.cs b/WhackerLinkConsoleV2/SettingsManager.cs
index 9e0acee..96690b9 100644
--- a/WhackerLinkConsoleV2/SettingsManager.cs
+++ b/WhackerLinkConsoleV2/SettingsManager.cs
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
-* Copyright (C) 2024 Caleb, K4PHP
+* Copyright (C) 2024-2025 Caleb, K4PHP
*
*/
diff --git a/WhackerLinkConsoleV2/WhackerLinkConsoleV2.csproj b/WhackerLinkConsoleV2/WhackerLinkConsoleV2.csproj
index 06be86e..f081958 100644
--- a/WhackerLinkConsoleV2/WhackerLinkConsoleV2.csproj
+++ b/WhackerLinkConsoleV2/WhackerLinkConsoleV2.csproj
@@ -6,6 +6,7 @@
disable
enable
true
+ AnyCPU;x64