CodeWalker/Forms/AwcForm.cs

269 lines
7.5 KiB
C#
Raw Normal View History

2017-09-21 18:33:05 +08:00
using CodeWalker.GameFiles;
using SharpDX.Multimedia;
using SharpDX.XAudio2;
using System;
using System.IO;
2018-01-10 13:50:35 +08:00
using System.Diagnostics;
2017-09-21 18:33:05 +08:00
using System.Windows.Forms;
namespace CodeWalker.Forms
{
public partial class AwcForm : Form
{
public AwcFile Awc { get; set; }
2018-01-10 13:50:35 +08:00
private XAudio2 xAudio2;
private MasteringVoice masteringVoice;
private AudioBuffer audioBuffer;
private SourceVoice sourceVoice;
2017-09-21 18:33:05 +08:00
private string fileName;
public string FileName
{
get { return fileName; }
set
{
fileName = value;
UpdateFormTitle();
}
}
public string FilePath { get; set; }
2018-01-10 13:50:35 +08:00
private enum PlayerState { Stopped, Playing, Paused };
private PlayerState playerState = PlayerState.Stopped;
2017-09-21 18:33:05 +08:00
2018-01-10 13:50:35 +08:00
private Stopwatch playtime;
private float trackLength;
2017-09-21 18:33:05 +08:00
public AwcForm()
{
InitializeComponent();
2018-01-10 13:50:35 +08:00
playtime = new Stopwatch();
}
2017-09-21 18:33:05 +08:00
private void UpdateFormTitle()
{
Text = fileName + " - AWC Player - CodeWalker by dexyfex";
}
public void LoadAwc(AwcFile awc)
{
Awc = awc;
DetailsPropertyGrid.SelectedObject = awc;
fileName = awc?.Name;
if (string.IsNullOrEmpty(fileName))
{
fileName = awc?.FileEntry?.Name;
}
PlayListView.Items.Clear();
if (awc.Audios != null)
{
foreach (var audio in awc.Audios)
{
var item = PlayListView.Items.Add(audio.Name);
item.SubItems.Add(audio.Type);
item.SubItems.Add(audio.LengthStr);
item.Tag = audio;
}
}
UpdateFormTitle();
}
2018-01-10 13:50:35 +08:00
private void Stop()
{
if (playerState != PlayerState.Stopped)
{
sourceVoice.DestroyVoice();
sourceVoice.Dispose();
audioBuffer.Stream.Dispose();
SetPlayerState(PlayerState.Stopped);
}
}
2017-09-21 18:33:05 +08:00
2018-01-10 13:50:35 +08:00
private void SetPlayerState(PlayerState newState)
{
if (playerState != newState)
{
switch (newState)
{
case PlayerState.Playing:
if (playerState == PlayerState.Stopped)
playtime.Reset();
playtime.Start();
break;
default:
playtime.Stop();
break;
}
playerState = newState;
}
}
2017-09-21 18:33:05 +08:00
2018-01-10 13:50:35 +08:00
private void InitializeAudio(AwcAudio audio)
{
trackLength = audio.Length;
if (xAudio2 == null)
{
xAudio2 = new XAudio2();
masteringVoice = new MasteringVoice(xAudio2);
}
Stream wavStream = audio.GetWavStream();
SoundStream soundStream = new SoundStream(wavStream);
audioBuffer = new AudioBuffer
{
Stream = soundStream.ToDataStream(),
AudioBytes = (int)soundStream.Length,
Flags = BufferFlags.EndOfStream
};
soundStream.Close();
wavStream.Close();
sourceVoice = new SourceVoice(xAudio2, soundStream.Format, true);
sourceVoice.SubmitSourceBuffer(audioBuffer, soundStream.DecodedPacketsInfo);
sourceVoice.SetVolume((float)VolumeTrackBar.Value / 100);
2017-09-21 18:33:05 +08:00
}
2018-01-10 13:50:35 +08:00
private void Play()
2017-09-21 18:33:05 +08:00
{
2018-01-10 13:50:35 +08:00
Stop();
2017-09-21 18:33:05 +08:00
2018-01-10 13:50:35 +08:00
if (PlayListView.SelectedItems.Count == 1)
{
var item = PlayListView.SelectedItems[0];
var audio = item.Tag as AwcAudio;
if (audio != null)
{
InitializeAudio(audio);
sourceVoice.Start();
SetPlayerState(PlayerState.Playing);
}
}
2017-09-21 18:33:05 +08:00
}
2018-01-10 13:50:35 +08:00
private void PlayPrevious()
{
Stop();
if (PlayListView.SelectedIndices.Count > 0)
{
var nextIndex = PlayListView.SelectedIndices[0] - 1;
if (nextIndex >= 0)
{
PlayListView.Items[nextIndex].Selected = true;
PlayListView.Items[nextIndex].Focused = true;
Play();
}
}
2017-09-21 18:33:05 +08:00
}
2018-01-10 13:50:35 +08:00
private void PlayNext()
{
Stop();
if (PlayListView.SelectedIndices.Count > 0)
{
var nextIndex = PlayListView.SelectedIndices[0] + 1;
if (nextIndex < PlayListView.Items.Count)
{
PlayListView.Items[nextIndex].Selected = true;
PlayListView.Items[nextIndex].Focused = true;
Play();
}
}
}
private void Pause()
2017-09-21 18:33:05 +08:00
{
2018-01-10 13:50:35 +08:00
if (playerState == PlayerState.Playing)
{
sourceVoice.Stop();
SetPlayerState(PlayerState.Paused);
}
2017-09-21 18:33:05 +08:00
}
2018-01-10 13:50:35 +08:00
private void Resume()
{
if (playerState == PlayerState.Paused)
{
sourceVoice.Start();
SetPlayerState(PlayerState.Playing);
}
}
2017-09-21 18:33:05 +08:00
private void PositionTrackBar_Scroll(object sender, EventArgs e)
{
}
private void PlayButton_Click(object sender, EventArgs e)
{
2018-01-10 13:50:35 +08:00
switch (playerState)
{
case PlayerState.Stopped:
Play();
break;
case PlayerState.Playing:
Pause();
break;
case PlayerState.Paused:
Resume();
break;
}
2017-09-21 18:33:05 +08:00
}
private void PrevButton_Click(object sender, EventArgs e)
{
2018-01-10 13:50:35 +08:00
PlayPrevious();
2017-09-21 18:33:05 +08:00
}
private void NextButton_Click(object sender, EventArgs e)
{
2018-01-10 13:50:35 +08:00
PlayNext();
2017-09-21 18:33:05 +08:00
}
private void VolumeTrackBar_Scroll(object sender, EventArgs e)
{
2018-01-10 13:50:35 +08:00
if (playerState == PlayerState.Playing)
sourceVoice.SetVolume((float)VolumeTrackBar.Value / 100);
}
private void Timer_Tick(object sender, EventArgs e)
{
if (playerState != PlayerState.Stopped)
{
int playedMs = (int)playtime.Elapsed.TotalMilliseconds;
int totalMs = (int)(trackLength * 1000);
PositionTrackBar.Maximum = totalMs;
PositionTrackBar.Value = playedMs < totalMs ? playedMs : totalMs;
}
else
{
PositionTrackBar.Value = 0;
}
}
private void PlayListView_DoubleClick(object sender, EventArgs e)
{
if (playerState == PlayerState.Playing)
Stop();
Play();
}
private void AwcForm_FormClosing(object sender, FormClosingEventArgs e)
{
Stop();
if (xAudio2 != null)
{
masteringVoice.Dispose();
xAudio2.Dispose();
}
}
2017-09-21 18:33:05 +08:00
}
}