Refactor the audio system; use a AudioManager to manage incoming audio; refactor how we check to send or not send audio

pull/1/head
firealarmss 11 months ago
parent 2102570d51
commit 3ad8b9b867

@ -0,0 +1,79 @@
/*
* WhackerLink - WhackerLinkConsoleV2
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2025 Caleb, K4PHP
*
*/
using NAudio.Wave;
using NAudio.Wave.SampleProviders;
using System.Collections.Generic;
using System.Diagnostics;
namespace WhackerLinkConsoleV2
{
public class AudioManager
{
private WaveOutEvent _waveOut;
private MixingSampleProvider _mixer;
private Dictionary<string, BufferedWaveProvider> _talkgroupProviders;
/// <summary>
/// Creates an instance of <see cref="AudioManager"/>
/// </summary>
public AudioManager()
{
_waveOut = new WaveOutEvent();
_talkgroupProviders = new Dictionary<string, BufferedWaveProvider>();
_mixer = new MixingSampleProvider(WaveFormat.CreateIeeeFloatWaveFormat(8000, 1))
{
ReadFully = true
};
_waveOut.Init(_mixer);
_waveOut.Play();
}
/// <summary>
/// Bad name, adds samples to a provider or creates a new provider
/// </summary>
/// <param name="talkgroupId"></param>
/// <param name="audioData"></param>
public void AddTalkgroupStream(string talkgroupId, byte[] audioData)
{
if (!_talkgroupProviders.ContainsKey(talkgroupId))
{
var provider = new BufferedWaveProvider(new WaveFormat(8000, 16, 1))
{
DiscardOnBufferOverflow = true
};
_talkgroupProviders[talkgroupId] = provider;
_mixer.AddMixerInput(provider.ToSampleProvider());
}
_talkgroupProviders[talkgroupId].AddSamples(audioData, 0, audioData.Length);
}
/// <summary>
/// Lop off the wave out
/// </summary>
public void Stop()
{
_waveOut.Stop();
}
}
}

@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2024 Caleb, K4PHP
* Copyright (C) 2024-2025 Caleb, K4PHP
*
*/
@ -53,7 +53,6 @@ namespace WhackerLinkConsoleV2
private double _offsetX;
private double _offsetY;
private bool _isDragging;
private bool _stopSending;
private SettingsManager _settingsManager = new SettingsManager();
private SelectedChannelsManager _selectedChannelsManager;
@ -62,8 +61,7 @@ namespace WhackerLinkConsoleV2
private WebSocketManager _webSocketManager = new WebSocketManager();
private readonly WaveInEvent _waveIn;
private readonly WaveOutEvent _waveOut;
private readonly BufferedWaveProvider _waveProvider;
private readonly AudioManager _audioManager;
public MainWindow()
{
@ -85,14 +83,7 @@ namespace WhackerLinkConsoleV2
_waveIn.StartRecording();
_waveOut = new WaveOutEvent();
_waveProvider = new BufferedWaveProvider(new WaveFormat(8000, 16, 1))
{
DiscardOnBufferOverflow = true
};
_waveOut.Init(_waveProvider);
_waveOut.Play();
_audioManager = new AudioManager();
_selectedChannelsManager.SelectedChannelsChanged += SelectedChannelsChanged;
Loaded += MainWindow_Loaded;
@ -331,7 +322,7 @@ namespace WhackerLinkConsoleV2
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
if (channel.IsSelected && channel.VoiceChannel != null && !_stopSending)
if (channel.IsSelected && channel.VoiceChannel != null && channel.PttState)
{
object voicePaket = new
{
@ -397,10 +388,10 @@ namespace WhackerLinkConsoleV2
_waveIn.DeviceNumber = inputDeviceIndex.Value;
_waveIn.StartRecording();
_waveOut.Stop();
_waveOut.DeviceNumber = outputDeviceIndex.Value;
_waveOut.Init(_waveProvider);
_waveOut.Play();
//_waveOut.Stop();
//_waveOut.DeviceNumber = outputDeviceIndex.Value;
//_waveOut.Init(_waveProvider);
//_waveOut.Play();
MessageBox.Show("Audio devices updated successfully.", "Success");
}
@ -462,8 +453,8 @@ namespace WhackerLinkConsoleV2
Task.Factory.StartNew(() =>
{
_waveProvider.ClearBuffer();
_waveProvider.AddSamples(combinedAudio, 0, combinedAudio.Length);
//_waveProvider.ClearBuffer();
_audioManager.AddTalkgroupStream(cpgChannel.Tgid, combinedAudio);
});
for (int i = 0; i < totalChunks; i++)
@ -659,6 +650,7 @@ namespace WhackerLinkConsoleV2
private void HandleReceivedAudio(AudioPacket audioPacket)
{
bool shouldReceive = false;
string talkgroupId = audioPacket.VoiceChannel.DstId;
foreach (ChannelBox channel in _selectedChannelsManager.GetSelectedChannels())
{
@ -667,14 +659,11 @@ namespace WhackerLinkConsoleV2
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
if (audioPacket.VoiceChannel.SrcId != system.Rid && audioPacket.VoiceChannel.Frequency == channel.VoiceChannel && audioPacket.VoiceChannel.DstId == cpgChannel.Tgid)
{
_waveProvider.AddSamples(audioPacket.Data, 0, audioPacket.Data.Length);
}
shouldReceive = true;
}
if (shouldReceive)
_waveProvider.AddSamples(audioPacket.Data, 0, audioPacket.Data.Length);
_audioManager.AddTalkgroupStream(talkgroupId, audioPacket.Data);
}
private void HandleVoiceRelease(GRP_VCH_RLS response)
@ -711,7 +700,6 @@ namespace WhackerLinkConsoleV2
if (channel.PttState && response.Status == (int)ResponseType.GRANT && response.Channel != null && response.SrcId == system.Rid && response.DstId == cpgChannel.Tgid)
{
channel.VoiceChannel = response.Channel;
_stopSending = false;
} else if (response.Status == (int)ResponseType.GRANT && response.SrcId != system.Rid && response.DstId == cpgChannel.Tgid)
{
channel.VoiceChannel = response.Channel;
@ -759,7 +747,6 @@ namespace WhackerLinkConsoleV2
}
else
{
//_stopSending = true;
GRP_VCH_RLS release = new GRP_VCH_RLS
{
SrcId = system.Rid,
@ -795,7 +782,6 @@ namespace WhackerLinkConsoleV2
}
else
{
_stopSending = true;
GRP_VCH_RLS release = new GRP_VCH_RLS
{
SrcId = system.Rid,

Loading…
Cancel
Save

Powered by TurnKey Linux.