256 lines
10 KiB
C#
256 lines
10 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Data;
|
|
using System.Windows.Documents;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Imaging;
|
|
using System.Windows.Navigation;
|
|
using System.Windows.Shapes;
|
|
using System.IO;
|
|
|
|
namespace RadioBroadcaster.Server
|
|
{
|
|
/// <summary>
|
|
/// Interaction logic for MainWindow.xaml
|
|
/// </summary>
|
|
public partial class MainWindow : Window
|
|
{
|
|
MediaEngine CurrentMediaEngine;
|
|
AudioTools audioTools = new AudioTools();
|
|
// File data
|
|
const string settingsFile = "settings.dat";
|
|
string currentRoot = System.Reflection.Assembly.GetExecutingAssembly().Location.Remove(System.Reflection.Assembly.GetExecutingAssembly().Location.LastIndexOf("\\")) + "\\";
|
|
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
LogManager.Init();
|
|
LogManager.Write("Starting software at " + DateTime.Now.ToShortDateString() +" "+ DateTime.Now.ToShortTimeString());
|
|
CurrentMediaEngine = new MediaEngine();
|
|
SerialManager.Init();
|
|
LogManager.Write("Loading Stations list");
|
|
Stations.LoadStations();
|
|
// Build UI objects
|
|
foreach (var item in Stations.sourceStations)
|
|
{
|
|
ListBoxItem listItem = new ListBoxItem() { Content = item.InternalName };
|
|
listItem.Selected += ListItem_Selected;
|
|
StationsList.Items.Add(listItem);
|
|
}
|
|
// Do loading of default settings
|
|
LogManager.Write("Loading settings");
|
|
BuildSettings();
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates or loads the settings file
|
|
/// </summary>
|
|
private void BuildSettings()
|
|
{
|
|
if (File.Exists(currentRoot + settingsFile))
|
|
{
|
|
string[] settings = File.ReadAllLines(currentRoot + settingsFile);
|
|
bool stationTag = false;
|
|
string[] stationsList = new string[0];
|
|
int stationsInc = 0;
|
|
foreach (var item in settings)
|
|
{
|
|
if (stationTag)
|
|
{
|
|
Array.Resize(ref stationsList, stationsList.Length + 1);
|
|
stationsList[stationsInc] = item;
|
|
stationsInc++;
|
|
}
|
|
else if (item.StartsWith("vol="))
|
|
{
|
|
CurrentMediaEngine.SetDefaultVolume = Convert.ToDouble(item.Replace("vol=", ""));
|
|
LogManager.Write("Volume: " + Convert.ToDouble(item.Replace("vol=", "")));
|
|
}
|
|
else if (item.StartsWith("txpow="))
|
|
{
|
|
// Not implemented
|
|
}
|
|
else if (item.StartsWith("freq="))
|
|
{
|
|
// Not implemented
|
|
}
|
|
else if (item.StartsWith("Default Station: (comment with // to skip)"))
|
|
{
|
|
stationTag = true;
|
|
}
|
|
}
|
|
bool[] validStations = new bool[stationsList.Length];
|
|
for (int i = 0; i < stationsList.Length; i++)
|
|
{
|
|
if (stationsList[i].StartsWith("//"))
|
|
{
|
|
validStations[i] = false;
|
|
}
|
|
else
|
|
{
|
|
validStations[i] = true;
|
|
}
|
|
}
|
|
string SelectedStationName = stationsList[Array.IndexOf(validStations, true)].Trim();
|
|
LogManager.Write("Station: " + SelectedStationName);
|
|
foreach (var item in Stations.sourceStations)
|
|
{
|
|
if (item.InternalName == SelectedStationName)
|
|
{
|
|
|
|
CurrentMediaEngine.SetPrimaryLocation = new Uri(item.URISource);
|
|
SerialManager.SetRDSStationName(item.RDS_StationName, true);
|
|
LogManager.Write("Setting RDS Station Name: " + item.RDS_StationName);
|
|
SerialManager.SetRDSStationData(item.RDS_Buffers[0]);
|
|
LogManager.Write("Setting RDS Station Data: " + item.RDS_Buffers[0]);
|
|
p1Loaded.Content = "Loaded";
|
|
LogManager.Write("Playing...");
|
|
CurrentMediaEngine.PlayPrimary();
|
|
p1Playing.Content = "Playing " + CurrentMediaEngine.SetPrimaryLocation;
|
|
}
|
|
}
|
|
}
|
|
else // Create a default settings file
|
|
{
|
|
LogManager.Write("Settings file did not exist, creating...");
|
|
string temp = "vol=0.7" + Environment.NewLine
|
|
+ "txpow=115" + Environment.NewLine
|
|
+ "freq=88.10 MHz" + Environment.NewLine
|
|
+ "Default Station: (comment with // to skip)" + Environment.NewLine;
|
|
foreach (var item in Stations.sourceStations)
|
|
{
|
|
temp = temp + item.InternalName + Environment.NewLine;
|
|
}
|
|
File.WriteAllText(currentRoot + settingsFile, temp);
|
|
}
|
|
}
|
|
|
|
private void ListItem_Selected(object sender, RoutedEventArgs e)
|
|
{
|
|
ListBoxItem listBoxItem = (ListBoxItem)sender;
|
|
PlayButton.Content = "Play " + listBoxItem.Content;
|
|
}
|
|
|
|
private void PlayButton_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (!CurrentMediaEngine.IsPlayingAudio)
|
|
{
|
|
CurrentMediaEngine.SetPrimaryLocation = new Uri(Stations.sourceStations[StationsList.SelectedIndex].URISource);
|
|
SerialManager.SetRDSStationName(Stations.sourceStations[StationsList.SelectedIndex].RDS_StationName, true);
|
|
SerialManager.SetRDSStationData(Stations.sourceStations[StationsList.SelectedIndex].RDS_Buffers[0]);
|
|
p1Loaded.Content = "Loaded";
|
|
CurrentMediaEngine.PlayPrimary();
|
|
p1Playing.Content = "Playing " + CurrentMediaEngine.SetPrimaryLocation;
|
|
}
|
|
else
|
|
{
|
|
CurrentMediaEngine.SetSecondaryLocation = new Uri(Stations.sourceStations[StationsList.SelectedIndex].URISource);
|
|
SerialManager.SetRDSStationName(Stations.sourceStations[StationsList.SelectedIndex].RDS_StationName, true);
|
|
SerialManager.SetRDSStationData(Stations.sourceStations[StationsList.SelectedIndex].RDS_Buffers[0]);
|
|
if (CurrentMediaEngine.CurrentPrimaryPlayer == 1)
|
|
{
|
|
p2Loaded.Content = "Loaded";
|
|
}
|
|
else
|
|
{
|
|
p1Loaded.Content = "Loaded";
|
|
}
|
|
CurrentMediaEngine.PlaySecondary();
|
|
if (CurrentMediaEngine.CurrentPrimaryPlayer == 1)
|
|
{
|
|
p2playing.Content = "Playing " + CurrentMediaEngine.SetSecondaryLocation;
|
|
}
|
|
else
|
|
{
|
|
p1Playing.Content = "Playing " + CurrentMediaEngine.SetSecondaryLocation;
|
|
}
|
|
audioTools.Crossfade(CurrentMediaEngine);
|
|
}
|
|
|
|
}
|
|
|
|
private void TX_Send_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
SerialManager.SetTXPower(TX.Value.ToString());
|
|
}
|
|
|
|
private void TX_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
|
{
|
|
|
|
}
|
|
|
|
private void LoadStation1_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
CurrentMediaEngine.SetPlayer1 = Stations.sourceStations[StationsList.SelectedIndex].URISource;
|
|
p1Loaded.Content = Stations.sourceStations[StationsList.SelectedIndex].RDS_StationName;
|
|
}
|
|
|
|
private void LoadStation2_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
CurrentMediaEngine.SetPlayer2 = Stations.sourceStations[StationsList.SelectedIndex].URISource;
|
|
p2Loaded.Content = Stations.sourceStations[StationsList.SelectedIndex].RDS_StationName;
|
|
}
|
|
|
|
private void Play_2_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if(CurrentMediaEngine.SetPlayer1 != null)
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Various tools for handling audio streams and to add effects
|
|
/// </summary>
|
|
class AudioTools
|
|
{
|
|
/// <summary>
|
|
/// Crossfades the audio between the two tracks
|
|
/// </summary>
|
|
/// <param name="playbackEngine">The playback engine in use</param>
|
|
/// <param name="steptime">the time (in ms) to wait between each step</param>
|
|
/// <param name="steps">The number of steps to take</param>
|
|
/// <param name="FullVolume">The maximum volume</param>
|
|
public void Crossfade(MediaEngine playbackEngine, int steptime = 40, int steps = 16, double FullVolume=0.7)
|
|
{
|
|
playbackEngine.SecondaryVolume = 0;
|
|
playbackEngine.SecondaryMuted = false;
|
|
double volumePerStep = FullVolume / steps;
|
|
while (steps > 0)
|
|
{
|
|
playbackEngine.PrimaryVolume = playbackEngine.PrimaryVolume - volumePerStep;
|
|
if (playbackEngine.SecondaryVolume > FullVolume - volumePerStep)
|
|
{
|
|
playbackEngine.SecondaryVolume = FullVolume;
|
|
}
|
|
else
|
|
{
|
|
playbackEngine.SecondaryVolume = playbackEngine.SecondaryVolume + volumePerStep;
|
|
}
|
|
Thread.Sleep(steptime);
|
|
steps--;
|
|
}
|
|
// Mute and reset volume
|
|
playbackEngine.PrimaryMuted = true;
|
|
playbackEngine.PrimaryVolume = FullVolume;
|
|
playbackEngine.StopPrimary();
|
|
playbackEngine.SwapPrimary();
|
|
}
|
|
/// <summary>
|
|
/// Exposes the underlying audio stream within an m3u encapsulation
|
|
/// </summary>
|
|
public void m3uDecapsulator()
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|