mirror of
https://github.com/lupettohf/kv4p-sharp.git
synced 2025-01-19 01:36:30 +08:00
V1, Library and example GUI Application.
This commit is contained in:
parent
357047bc40
commit
0315d8d7dc
|
@ -3,22 +3,36 @@ using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using NAudio.Wave;
|
using NAudio.Wave;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
namespace RadioControllerApp
|
namespace RadioControllerApp
|
||||||
{
|
{
|
||||||
public class FormRadio : Form
|
public class FormRadio : Form
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Pre-buffering fields
|
||||||
|
private const int PreBufferSize = 5000; // Adjust as needed
|
||||||
|
private ConcurrentQueue<byte[]> preBufferQueue = new ConcurrentQueue<byte[]>();
|
||||||
|
private int preBufferedBytes = 0;
|
||||||
|
private bool preBufferingComplete = false;
|
||||||
|
|
||||||
private RadioController radioController;
|
private RadioController radioController;
|
||||||
private WaveInEvent waveIn;
|
private WaveInEvent waveIn;
|
||||||
private BufferedWaveProvider receivedAudioBuffer;
|
private BufferedWaveProvider receivedAudioBuffer;
|
||||||
private WaveOutEvent waveOut;
|
private WaveOutEvent waveOut;
|
||||||
|
|
||||||
private bool isRecording = false;
|
private bool isRecording = false;
|
||||||
|
private bool isTransmitting = false;
|
||||||
|
|
||||||
|
// PTT Key Handling
|
||||||
|
private Keys pttKey = Keys.Space;
|
||||||
|
private bool waitingForPTTKey = false;
|
||||||
|
|
||||||
// UI Controls
|
// UI Controls
|
||||||
private TextBox txtPortName;
|
private TextBox txtPortName;
|
||||||
private Button btnOpenConnection;
|
private Button btnOpenConnection;
|
||||||
private Button btnCloseConnection;
|
private Button btnCloseConnection;
|
||||||
private Button btnInitialize;
|
|
||||||
|
|
||||||
private TextBox txtTXFrequency;
|
private TextBox txtTXFrequency;
|
||||||
private TextBox txtRXFrequency;
|
private TextBox txtRXFrequency;
|
||||||
|
@ -31,35 +45,38 @@ namespace RadioControllerApp
|
||||||
private CheckBox chkLowpass;
|
private CheckBox chkLowpass;
|
||||||
private Button btnSetFilters;
|
private Button btnSetFilters;
|
||||||
|
|
||||||
private Button btnStartRX;
|
private Button btnSetPTTKey;
|
||||||
private Button btnStartTX;
|
|
||||||
private Button btnEndTX;
|
|
||||||
private Button btnStop;
|
|
||||||
|
|
||||||
private Button btnStartRecording;
|
|
||||||
private Button btnStopRecording;
|
|
||||||
private Button btnPlayReceivedAudio;
|
|
||||||
|
|
||||||
private TextBox txtStatus;
|
private TextBox txtStatus;
|
||||||
|
|
||||||
|
private Panel pnlStatusIndicator;
|
||||||
|
|
||||||
public FormRadio()
|
public FormRadio()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InitializeRadioController();
|
InitializeRadioController();
|
||||||
|
LoadConfigurations();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
this.AutoScaleMode = AutoScaleMode.Dpi; // Enable DPI scaling
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormRadio));
|
||||||
|
SuspendLayout();
|
||||||
// Form properties
|
//
|
||||||
this.Text = "Radio Controller";
|
// FormRadio
|
||||||
this.Size = new System.Drawing.Size(800, 700);
|
//
|
||||||
this.MinimumSize = new System.Drawing.Size(600, 600);
|
AutoScaleDimensions = new SizeF(144F, 144F);
|
||||||
this.FormClosing += FormRadio_FormClosing;
|
AutoScaleMode = AutoScaleMode.Dpi;
|
||||||
|
ClientSize = new Size(778, 644);
|
||||||
// Initialize controls
|
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||||
InitializeControls();
|
KeyPreview = true;
|
||||||
|
MinimumSize = new Size(600, 600);
|
||||||
|
Name = "FormRadio";
|
||||||
|
Text = "Radio Controller";
|
||||||
|
FormClosing += FormRadio_FormClosing;
|
||||||
|
KeyDown += FormRadio_KeyDown;
|
||||||
|
KeyUp += FormRadio_KeyUp;
|
||||||
|
ResumeLayout(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeControls()
|
private void InitializeControls()
|
||||||
|
@ -74,33 +91,37 @@ namespace RadioControllerApp
|
||||||
};
|
};
|
||||||
this.Controls.Add(mainLayout);
|
this.Controls.Add(mainLayout);
|
||||||
|
|
||||||
// Adjust row styles
|
// Insert row styles
|
||||||
|
mainLayout.RowStyles.Insert(0, new RowStyle(SizeType.Absolute, 20F)); // Status Indicator
|
||||||
mainLayout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // Connection Controls
|
mainLayout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // Connection Controls
|
||||||
mainLayout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // Frequency Controls
|
mainLayout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // Frequency Controls
|
||||||
mainLayout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // Filter Controls
|
mainLayout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // Filter Controls
|
||||||
mainLayout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // Mode Controls
|
|
||||||
mainLayout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // Audio Controls
|
mainLayout.RowStyles.Add(new RowStyle(SizeType.AutoSize)); // Audio Controls
|
||||||
mainLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 100F)); // Status TextBox
|
mainLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 100F)); // Status TextBox
|
||||||
|
|
||||||
|
// Status Indicator Panel
|
||||||
|
pnlStatusIndicator = new Panel
|
||||||
|
{
|
||||||
|
Height = 20,
|
||||||
|
Dock = DockStyle.Fill,
|
||||||
|
BackColor = System.Drawing.Color.Green // Assume green for RX
|
||||||
|
};
|
||||||
|
mainLayout.Controls.Add(pnlStatusIndicator, 0, 0);
|
||||||
|
|
||||||
// Connection Controls GroupBox
|
// Connection Controls GroupBox
|
||||||
GroupBox grpConnection = CreateConnectionControls();
|
GroupBox grpConnection = CreateConnectionControls();
|
||||||
grpConnection.Dock = DockStyle.Fill;
|
grpConnection.Dock = DockStyle.Fill;
|
||||||
mainLayout.Controls.Add(grpConnection, 0, 0);
|
mainLayout.Controls.Add(grpConnection, 0, 1);
|
||||||
|
|
||||||
// Frequency Controls GroupBox
|
// Frequency Controls GroupBox
|
||||||
GroupBox grpFrequency = CreateFrequencyControls();
|
GroupBox grpFrequency = CreateFrequencyControls();
|
||||||
grpFrequency.Dock = DockStyle.Fill;
|
grpFrequency.Dock = DockStyle.Fill;
|
||||||
mainLayout.Controls.Add(grpFrequency, 0, 1);
|
mainLayout.Controls.Add(grpFrequency, 0, 2);
|
||||||
|
|
||||||
// Filter Controls GroupBox
|
// Filter Controls GroupBox
|
||||||
GroupBox grpFilters = CreateFilterControls();
|
GroupBox grpFilters = CreateFilterControls();
|
||||||
grpFilters.Dock = DockStyle.Fill;
|
grpFilters.Dock = DockStyle.Fill;
|
||||||
mainLayout.Controls.Add(grpFilters, 0, 2);
|
mainLayout.Controls.Add(grpFilters, 0, 3);
|
||||||
|
|
||||||
// Mode Controls GroupBox
|
|
||||||
GroupBox grpModes = CreateModeControls();
|
|
||||||
grpModes.Dock = DockStyle.Fill;
|
|
||||||
mainLayout.Controls.Add(grpModes, 0, 3);
|
|
||||||
|
|
||||||
// Audio Controls GroupBox
|
// Audio Controls GroupBox
|
||||||
GroupBox grpAudio = CreateAudioControls();
|
GroupBox grpAudio = CreateAudioControls();
|
||||||
|
@ -130,7 +151,7 @@ namespace RadioControllerApp
|
||||||
TableLayoutPanel layout = new TableLayoutPanel
|
TableLayoutPanel layout = new TableLayoutPanel
|
||||||
{
|
{
|
||||||
Dock = DockStyle.Fill,
|
Dock = DockStyle.Fill,
|
||||||
ColumnCount = 5,
|
ColumnCount = 4,
|
||||||
AutoSize = true
|
AutoSize = true
|
||||||
};
|
};
|
||||||
grpConnection.Controls.Add(layout);
|
grpConnection.Controls.Add(layout);
|
||||||
|
@ -139,23 +160,19 @@ namespace RadioControllerApp
|
||||||
txtPortName = new TextBox { Text = "COM3", Anchor = AnchorStyles.Left };
|
txtPortName = new TextBox { Text = "COM3", Anchor = AnchorStyles.Left };
|
||||||
btnOpenConnection = new Button { Text = "Open Connection", AutoSize = true };
|
btnOpenConnection = new Button { Text = "Open Connection", AutoSize = true };
|
||||||
btnCloseConnection = new Button { Text = "Close Connection", AutoSize = true };
|
btnCloseConnection = new Button { Text = "Close Connection", AutoSize = true };
|
||||||
btnInitialize = new Button { Text = "Initialize", AutoSize = true };
|
|
||||||
|
|
||||||
btnOpenConnection.Click += btnOpenConnection_Click;
|
btnOpenConnection.Click += btnOpenConnection_Click;
|
||||||
btnCloseConnection.Click += btnCloseConnection_Click;
|
btnCloseConnection.Click += btnCloseConnection_Click;
|
||||||
btnInitialize.Click += btnInitialize_Click;
|
|
||||||
|
|
||||||
layout.Controls.Add(lblPortName, 0, 0);
|
layout.Controls.Add(lblPortName, 0, 0);
|
||||||
layout.Controls.Add(txtPortName, 1, 0);
|
layout.Controls.Add(txtPortName, 1, 0);
|
||||||
layout.Controls.Add(btnOpenConnection, 2, 0);
|
layout.Controls.Add(btnOpenConnection, 2, 0);
|
||||||
layout.Controls.Add(btnCloseConnection, 3, 0);
|
layout.Controls.Add(btnCloseConnection, 3, 0);
|
||||||
layout.Controls.Add(btnInitialize, 4, 0);
|
|
||||||
|
|
||||||
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize)); // Label
|
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize)); // Label
|
||||||
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize)); // TextBox
|
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize)); // TextBox
|
||||||
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33F)); // Button
|
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); // Button
|
||||||
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33F)); // Button
|
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); // Button
|
||||||
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 34F)); // Button
|
|
||||||
|
|
||||||
return grpConnection;
|
return grpConnection;
|
||||||
}
|
}
|
||||||
|
@ -243,41 +260,6 @@ namespace RadioControllerApp
|
||||||
return grpFilters;
|
return grpFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GroupBox CreateModeControls()
|
|
||||||
{
|
|
||||||
GroupBox grpModes = new GroupBox
|
|
||||||
{
|
|
||||||
Text = "Mode Controls",
|
|
||||||
AutoSize = true,
|
|
||||||
Dock = DockStyle.Fill
|
|
||||||
};
|
|
||||||
|
|
||||||
FlowLayoutPanel layout = new FlowLayoutPanel
|
|
||||||
{
|
|
||||||
Dock = DockStyle.Fill,
|
|
||||||
AutoSize = true,
|
|
||||||
WrapContents = false,
|
|
||||||
};
|
|
||||||
grpModes.Controls.Add(layout);
|
|
||||||
|
|
||||||
btnStartRX = new Button { Text = "Start RX Mode", AutoSize = true };
|
|
||||||
btnStartTX = new Button { Text = "Start TX Mode", AutoSize = true };
|
|
||||||
btnEndTX = new Button { Text = "End TX Mode", AutoSize = true };
|
|
||||||
btnStop = new Button { Text = "Stop", AutoSize = true };
|
|
||||||
|
|
||||||
btnStartRX.Click += btnStartRX_Click;
|
|
||||||
btnStartTX.Click += btnStartTX_Click;
|
|
||||||
btnEndTX.Click += btnEndTX_Click;
|
|
||||||
btnStop.Click += btnStop_Click;
|
|
||||||
|
|
||||||
layout.Controls.Add(btnStartRX);
|
|
||||||
layout.Controls.Add(btnStartTX);
|
|
||||||
layout.Controls.Add(btnEndTX);
|
|
||||||
layout.Controls.Add(btnStop);
|
|
||||||
|
|
||||||
return grpModes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private GroupBox CreateAudioControls()
|
private GroupBox CreateAudioControls()
|
||||||
{
|
{
|
||||||
GroupBox grpAudio = new GroupBox
|
GroupBox grpAudio = new GroupBox
|
||||||
|
@ -295,17 +277,10 @@ namespace RadioControllerApp
|
||||||
};
|
};
|
||||||
grpAudio.Controls.Add(layout);
|
grpAudio.Controls.Add(layout);
|
||||||
|
|
||||||
btnStartRecording = new Button { Text = "Start Recording", AutoSize = true };
|
btnSetPTTKey = new Button { Text = "Set PTT Key", AutoSize = true };
|
||||||
btnStopRecording = new Button { Text = "Stop Recording", AutoSize = true };
|
btnSetPTTKey.Click += btnSetPTTKey_Click;
|
||||||
btnPlayReceivedAudio = new Button { Text = "Play Received Audio", AutoSize = true };
|
|
||||||
|
|
||||||
btnStartRecording.Click += btnStartRecording_Click;
|
layout.Controls.Add(btnSetPTTKey);
|
||||||
btnStopRecording.Click += btnStopRecording_Click;
|
|
||||||
btnPlayReceivedAudio.Click += btnPlayReceivedAudio_Click;
|
|
||||||
|
|
||||||
layout.Controls.Add(btnStartRecording);
|
|
||||||
layout.Controls.Add(btnStopRecording);
|
|
||||||
layout.Controls.Add(btnPlayReceivedAudio);
|
|
||||||
|
|
||||||
return grpAudio;
|
return grpAudio;
|
||||||
}
|
}
|
||||||
|
@ -315,9 +290,16 @@ namespace RadioControllerApp
|
||||||
// Disable controls that require an open connection
|
// Disable controls that require an open connection
|
||||||
ToggleControls(false);
|
ToggleControls(false);
|
||||||
|
|
||||||
receivedAudioBuffer = new BufferedWaveProvider(new WaveFormat(44100, 16, 1));
|
receivedAudioBuffer = new BufferedWaveProvider(new WaveFormat(44100, 8, 1))
|
||||||
|
{
|
||||||
|
BufferDuration = TimeSpan.FromSeconds(5),
|
||||||
|
DiscardOnBufferOverflow = true
|
||||||
|
};
|
||||||
|
waveOut = new WaveOutEvent();
|
||||||
|
waveOut.Init(receivedAudioBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void btnOpenConnection_Click(object sender, EventArgs e)
|
private void btnOpenConnection_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -334,7 +316,14 @@ namespace RadioControllerApp
|
||||||
radioController.AudioDataReceived += RadioController_AudioDataReceived;
|
radioController.AudioDataReceived += RadioController_AudioDataReceived;
|
||||||
radioController.OpenConnection();
|
radioController.OpenConnection();
|
||||||
|
|
||||||
|
radioController.Initialize();
|
||||||
|
btnTune_Click(null, null);
|
||||||
|
// Start RX mode
|
||||||
|
isTransmitting = false;
|
||||||
|
UpdateStatusIndicator(false);
|
||||||
|
|
||||||
AppendStatus($"Connection opened on {portName}.");
|
AppendStatus($"Connection opened on {portName}.");
|
||||||
|
radioController.StartRXMode();
|
||||||
ToggleControls(true);
|
ToggleControls(true);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -362,19 +351,6 @@ namespace RadioControllerApp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnInitialize_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
radioController.Initialize();
|
|
||||||
AppendStatus("Radio initialized.");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
AppendStatus($"Error initializing radio: {ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void btnTune_Click(object sender, EventArgs e)
|
private void btnTune_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -410,59 +386,44 @@ namespace RadioControllerApp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnStartRX_Click(object sender, EventArgs e)
|
private void btnSetPTTKey_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
try
|
AppendStatus("Press any key to set as PTT.");
|
||||||
{
|
waitingForPTTKey = true;
|
||||||
radioController.StartRXMode();
|
|
||||||
AppendStatus("Started RX mode.");
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
|
private void FormRadio_KeyDown(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
AppendStatus($"Error starting RX mode: {ex.Message}");
|
if (waitingForPTTKey)
|
||||||
|
{
|
||||||
|
pttKey = e.KeyCode;
|
||||||
|
waitingForPTTKey = false;
|
||||||
|
AppendStatus($"PTT key set to: {pttKey}");
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
else if (e.KeyCode == pttKey)
|
||||||
|
{
|
||||||
|
if (!isTransmitting)
|
||||||
|
{
|
||||||
|
StartTransmission();
|
||||||
|
}
|
||||||
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnStartTX_Click(object sender, EventArgs e)
|
private void FormRadio_KeyUp(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
if (!waitingForPTTKey && e.KeyCode == pttKey)
|
||||||
{
|
{
|
||||||
radioController.StartTXMode();
|
if (isTransmitting)
|
||||||
AppendStatus("Started TX mode.");
|
{
|
||||||
|
StopTransmission();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
e.Handled = true;
|
||||||
{
|
|
||||||
AppendStatus($"Error starting TX mode: {ex.Message}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnEndTX_Click(object sender, EventArgs e)
|
private void StartTransmission()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
radioController.EndTXMode();
|
|
||||||
AppendStatus("Ended TX mode.");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
AppendStatus($"Error ending TX mode: {ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void btnStop_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
radioController.Stop();
|
|
||||||
AppendStatus("Radio stopped.");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
AppendStatus($"Error stopping radio: {ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void btnStartRecording_Click(object sender, EventArgs e)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -473,39 +434,45 @@ namespace RadioControllerApp
|
||||||
}
|
}
|
||||||
|
|
||||||
radioController.StartTXMode();
|
radioController.StartTXMode();
|
||||||
isRecording = true;
|
isTransmitting = true;
|
||||||
|
|
||||||
waveIn = new WaveInEvent();
|
waveIn = new WaveInEvent();
|
||||||
waveIn.WaveFormat = new WaveFormat(44100, 16, 1);
|
waveIn.WaveFormat = new WaveFormat(44100, 8, 1);
|
||||||
waveIn.DataAvailable += WaveIn_DataAvailable;
|
waveIn.DataAvailable += WaveIn_DataAvailable;
|
||||||
waveIn.StartRecording();
|
waveIn.StartRecording();
|
||||||
|
|
||||||
AppendStatus("Recording started.");
|
AppendStatus("Transmission started.");
|
||||||
|
|
||||||
|
// Update status indicator
|
||||||
|
UpdateStatusIndicator(true);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
AppendStatus($"Error starting recording: {ex.Message}");
|
AppendStatus($"Error starting transmission: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnStopRecording_Click(object sender, EventArgs e)
|
private void StopTransmission()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (isRecording && waveIn != null)
|
if (isTransmitting && waveIn != null)
|
||||||
{
|
{
|
||||||
waveIn.StopRecording();
|
waveIn.StopRecording();
|
||||||
waveIn.Dispose();
|
waveIn.Dispose();
|
||||||
waveIn = null;
|
waveIn = null;
|
||||||
isRecording = false;
|
isTransmitting = false;
|
||||||
|
|
||||||
radioController.EndTXMode();
|
radioController.EndTXMode();
|
||||||
AppendStatus("Recording stopped.");
|
AppendStatus("Transmission stopped.");
|
||||||
|
radioController.StartRXMode();
|
||||||
|
// Update status indicator
|
||||||
|
UpdateStatusIndicator(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
AppendStatus($"Error stopping recording: {ex.Message}");
|
AppendStatus($"Error stopping transmission: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,13 +480,13 @@ namespace RadioControllerApp
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (isRecording && radioController != null)
|
if (isTransmitting && radioController != null)
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[e.BytesRecorded];
|
byte[] buffer = new byte[e.BytesRecorded];
|
||||||
Array.Copy(e.Buffer, buffer, e.BytesRecorded);
|
Array.Copy(e.Buffer, buffer, e.BytesRecorded);
|
||||||
|
|
||||||
// Convert audio data to the required format if necessary
|
// Send audio data asynchronously
|
||||||
await radioController.SendAudioDataAsync(buffer);
|
await radioController.SendAudioDataAsync(buffer, 0, buffer.Length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -528,25 +495,6 @@ namespace RadioControllerApp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnPlayReceivedAudio_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (waveOut == null)
|
|
||||||
{
|
|
||||||
waveOut = new WaveOutEvent();
|
|
||||||
waveOut.Init(receivedAudioBuffer);
|
|
||||||
}
|
|
||||||
waveOut.Play();
|
|
||||||
|
|
||||||
AppendStatus("Playing received audio.");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
AppendStatus($"Error playing received audio: {ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RadioController_ErrorOccurred(object sender, ErrorEventArgs e)
|
private void RadioController_ErrorOccurred(object sender, ErrorEventArgs e)
|
||||||
{
|
{
|
||||||
AppendStatus($"Error: {e.GetException().Message}");
|
AppendStatus($"Error: {e.GetException().Message}");
|
||||||
|
@ -554,9 +502,39 @@ namespace RadioControllerApp
|
||||||
|
|
||||||
private void RadioController_AudioDataReceived(object sender, byte[] data)
|
private void RadioController_AudioDataReceived(object sender, byte[] data)
|
||||||
{
|
{
|
||||||
// Buffer the received audio data
|
Console.WriteLine($"AudioDataReceived called with {data.Length} bytes");
|
||||||
|
|
||||||
|
if (!preBufferingComplete)
|
||||||
|
{
|
||||||
|
preBufferQueue.Enqueue(data);
|
||||||
|
preBufferedBytes += data.Length;
|
||||||
|
|
||||||
|
if (preBufferedBytes >= PreBufferSize)
|
||||||
|
{
|
||||||
|
// Pre-buffering complete, start playback
|
||||||
|
preBufferingComplete = true;
|
||||||
|
|
||||||
|
// Add all pre-buffered data to the buffer
|
||||||
|
while (preBufferQueue.TryDequeue(out byte[] preBufferData))
|
||||||
|
{
|
||||||
|
receivedAudioBuffer.AddSamples(preBufferData, 0, preBufferData.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start playback
|
||||||
|
waveOut.Play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add received audio data to the buffer
|
||||||
receivedAudioBuffer.AddSamples(data, 0, data.Length);
|
receivedAudioBuffer.AddSamples(data, 0, data.Length);
|
||||||
AppendStatus($"Audio data received. Length: {data.Length} bytes.");
|
|
||||||
|
// Ensure playback is ongoing
|
||||||
|
if (waveOut.PlaybackState != PlaybackState.Playing)
|
||||||
|
{
|
||||||
|
waveOut.Play();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AppendStatus(string message)
|
private void AppendStatus(string message)
|
||||||
|
@ -571,19 +549,30 @@ namespace RadioControllerApp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateStatusIndicator(bool isTransmitting)
|
||||||
|
{
|
||||||
|
if (pnlStatusIndicator.InvokeRequired)
|
||||||
|
{
|
||||||
|
pnlStatusIndicator.Invoke(new Action(() => UpdateStatusIndicator(isTransmitting)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isTransmitting)
|
||||||
|
{
|
||||||
|
pnlStatusIndicator.BackColor = System.Drawing.Color.Red;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pnlStatusIndicator.BackColor = System.Drawing.Color.Green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ToggleControls(bool isEnabled)
|
private void ToggleControls(bool isEnabled)
|
||||||
{
|
{
|
||||||
btnInitialize.Enabled = isEnabled;
|
|
||||||
btnTune.Enabled = isEnabled;
|
btnTune.Enabled = isEnabled;
|
||||||
btnSetFilters.Enabled = isEnabled;
|
btnSetFilters.Enabled = isEnabled;
|
||||||
btnStartRX.Enabled = isEnabled;
|
btnSetPTTKey.Enabled = isEnabled;
|
||||||
btnStartTX.Enabled = isEnabled;
|
|
||||||
btnEndTX.Enabled = isEnabled;
|
|
||||||
btnStop.Enabled = isEnabled;
|
|
||||||
|
|
||||||
btnStartRecording.Enabled = isEnabled;
|
|
||||||
btnStopRecording.Enabled = isEnabled;
|
|
||||||
btnPlayReceivedAudio.Enabled = isEnabled;
|
|
||||||
|
|
||||||
// Disable connection buttons appropriately
|
// Disable connection buttons appropriately
|
||||||
btnOpenConnection.Enabled = !isEnabled;
|
btnOpenConnection.Enabled = !isEnabled;
|
||||||
|
@ -610,6 +599,77 @@ namespace RadioControllerApp
|
||||||
waveOut.Dispose();
|
waveOut.Dispose();
|
||||||
waveOut = null;
|
waveOut = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save configurations
|
||||||
|
SaveConfigurations();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadConfigurations()
|
||||||
|
{
|
||||||
|
string configFile = "config.ini";
|
||||||
|
if (File.Exists(configFile))
|
||||||
|
{
|
||||||
|
string[] lines = File.ReadAllLines(configFile);
|
||||||
|
foreach (string line in lines)
|
||||||
|
{
|
||||||
|
if (line.StartsWith("PortName="))
|
||||||
|
{
|
||||||
|
txtPortName.Text = line.Substring("PortName=".Length);
|
||||||
|
}
|
||||||
|
else if (line.StartsWith("PTTKey="))
|
||||||
|
{
|
||||||
|
if (Enum.TryParse(line.Substring("PTTKey=".Length), out Keys key))
|
||||||
|
{
|
||||||
|
pttKey = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (line.StartsWith("TXFrequency="))
|
||||||
|
{
|
||||||
|
txtTXFrequency.Text = line.Substring("TXFrequency=".Length);
|
||||||
|
}
|
||||||
|
else if (line.StartsWith("RXFrequency="))
|
||||||
|
{
|
||||||
|
txtRXFrequency.Text = line.Substring("RXFrequency=".Length);
|
||||||
|
}
|
||||||
|
else if (line.StartsWith("Tone="))
|
||||||
|
{
|
||||||
|
txtTone.Text = line.Substring("Tone=".Length);
|
||||||
|
}
|
||||||
|
else if (line.StartsWith("SquelchLevel="))
|
||||||
|
{
|
||||||
|
txtSquelchLevel.Text = line.Substring("SquelchLevel=".Length);
|
||||||
|
}
|
||||||
|
else if (line.StartsWith("Emphasis="))
|
||||||
|
{
|
||||||
|
chkEmphasis.Checked = line.Substring("Emphasis=".Length) == "True";
|
||||||
|
}
|
||||||
|
else if (line.StartsWith("Highpass="))
|
||||||
|
{
|
||||||
|
chkHighpass.Checked = line.Substring("Highpass=".Length) == "True";
|
||||||
|
}
|
||||||
|
else if (line.StartsWith("Lowpass="))
|
||||||
|
{
|
||||||
|
chkLowpass.Checked = line.Substring("Lowpass=".Length) == "True";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveConfigurations()
|
||||||
|
{
|
||||||
|
string configFile = "config.ini";
|
||||||
|
using (StreamWriter writer = new StreamWriter(configFile))
|
||||||
|
{
|
||||||
|
writer.WriteLine($"PortName={txtPortName.Text}");
|
||||||
|
writer.WriteLine($"PTTKey={pttKey}");
|
||||||
|
writer.WriteLine($"TXFrequency={txtTXFrequency.Text}");
|
||||||
|
writer.WriteLine($"RXFrequency={txtRXFrequency.Text}");
|
||||||
|
writer.WriteLine($"Tone={txtTone.Text}");
|
||||||
|
writer.WriteLine($"SquelchLevel={txtSquelchLevel.Text}");
|
||||||
|
writer.WriteLine($"Emphasis={chkEmphasis.Checked}");
|
||||||
|
writer.WriteLine($"Highpass={chkHighpass.Checked}");
|
||||||
|
writer.WriteLine($"Lowpass={chkLowpass.Checked}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,4 +117,66 @@
|
||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
|
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
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
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -2,13 +2,29 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
<TargetFramework>net7.0-windows</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||||
|
<Company>Monocul.us</Company>
|
||||||
|
<Authors>Andrea Santaniello</Authors>
|
||||||
|
<Description>Radio GUI for KV4P radio</Description>
|
||||||
|
<PackageIcon>icon-lg-dark.png</PackageIcon>
|
||||||
|
<ApplicationIcon>icon-lg-dark.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="icon-lg-dark.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="E:\malattie\malattie_json\icon-lg-dark.png">
|
||||||
|
<Pack>True</Pack>
|
||||||
|
<PackagePath>\</PackagePath>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="NAudio" Version="2.2.1" />
|
<PackageReference Include="NAudio" Version="2.2.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
BIN
RadioGUI/icon-lg-dark.ico
Normal file
BIN
RadioGUI/icon-lg-dark.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO.Ports;
|
using System.IO.Ports;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
@ -73,6 +74,7 @@ public class RadioController : IDisposable
|
||||||
WriteTimeout = writeTimeout
|
WriteTimeout = writeTimeout
|
||||||
};
|
};
|
||||||
serialPort.DataReceived += SerialPort_DataReceived;
|
serialPort.DataReceived += SerialPort_DataReceived;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OpenConnection()
|
public void OpenConnection()
|
||||||
|
@ -181,7 +183,7 @@ public class RadioController : IDisposable
|
||||||
SendCommand(ESP32Command.FILTERS, paramsStr);
|
SendCommand(ESP32Command.FILTERS, paramsStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendAudioDataAsync(byte[] audioData, CancellationToken cancellationToken = default)
|
public async Task SendAudioDataAsync(byte[] audioData, int offset, int count, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
lock (_syncLock)
|
lock (_syncLock)
|
||||||
{
|
{
|
||||||
|
@ -193,10 +195,10 @@ public class RadioController : IDisposable
|
||||||
int chunkSize = 512;
|
int chunkSize = 512;
|
||||||
Stopwatch stopwatch = new Stopwatch();
|
Stopwatch stopwatch = new Stopwatch();
|
||||||
|
|
||||||
for (int i = 0; i < audioData.Length; i += chunkSize)
|
for (int i = offset; i < count; i += chunkSize)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
int remaining = audioData.Length - i;
|
int remaining = count - i;
|
||||||
int size = remaining > chunkSize ? chunkSize : remaining;
|
int size = remaining > chunkSize ? chunkSize : remaining;
|
||||||
byte[] chunk = new byte[size];
|
byte[] chunk = new byte[size];
|
||||||
Array.Copy(audioData, i, chunk, 0, size);
|
Array.Copy(audioData, i, chunk, 0, size);
|
||||||
|
@ -217,6 +219,7 @@ public class RadioController : IDisposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
|
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
byte[] receivedData = null;
|
byte[] receivedData = null;
|
||||||
|
@ -246,7 +249,7 @@ public class RadioController : IDisposable
|
||||||
{
|
{
|
||||||
mode = currentMode;
|
mode = currentMode;
|
||||||
}
|
}
|
||||||
if (mode == RadioMode.RX)
|
if (mode != RadioMode.TX)
|
||||||
{
|
{
|
||||||
// Raise an event with the received audio data
|
// Raise an event with the received audio data
|
||||||
OnAudioDataReceived(data);
|
OnAudioDataReceived(data);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<RootNamespace>kv4p_sharp</RootNamespace>
|
<RootNamespace>kv4p_sharp</RootNamespace>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user