Play chatter without temp file

Direct from a MemoryStream, no need for temp file
This commit is contained in:
Kurt 2023-12-20 08:58:40 -08:00
parent 54d3f377e9
commit e885a7d4f4

View file

@ -12,7 +12,6 @@ public partial class SAV_Chatter : Form
private readonly SaveFile SAV; private readonly SaveFile SAV;
private readonly IChatter Chatter; private readonly IChatter Chatter;
private readonly string TempPath = Path.Combine(Path.GetTempPath(), "Recording.wav");
private readonly SoundPlayer Sounds = new(); private readonly SoundPlayer Sounds = new();
public SAV_Chatter(SaveFile sav) public SAV_Chatter(SaveFile sav)
@ -22,7 +21,6 @@ public partial class SAV_Chatter : Form
SAV = (Origin = sav).Clone(); SAV = (Origin = sav).Clone();
Chatter = SAV is SAV5 s5 ? s5.Chatter : ((SAV4)SAV).Chatter; Chatter = SAV is SAV5 s5 ? s5.Chatter : ((SAV4)SAV).Chatter;
DeleteTempFile();
CHK_Initialized.Checked = Chatter.Initialized; CHK_Initialized.Checked = Chatter.Initialized;
MT_Confusion.Text = Chatter.ConfusionChance.ToString(); MT_Confusion.Text = Chatter.ConfusionChance.ToString();
} }
@ -51,7 +49,6 @@ public partial class SAV_Chatter : Form
byte[] data = File.ReadAllBytes(path); byte[] data = File.ReadAllBytes(path);
data.CopyTo(Chatter.Recording); data.CopyTo(Chatter.Recording);
DeleteTempFile();
CHK_Initialized.Checked = Chatter.Initialized = true; CHK_Initialized.Checked = Chatter.Initialized = true;
MT_Confusion.Text = Chatter.ConfusionChance.ToString(); MT_Confusion.Text = Chatter.ConfusionChance.ToString();
} }
@ -78,14 +75,15 @@ public partial class SAV_Chatter : Form
File.WriteAllBytes(sfd.FileName, ConvertPCMToWAV(Chatter.Recording)); File.WriteAllBytes(sfd.FileName, ConvertPCMToWAV(Chatter.Recording));
} }
private async void B_PlayRecording_Click(object sender, EventArgs e) private void B_PlayRecording_Click(object sender, EventArgs e)
{ {
if (!Chatter.Initialized && !Chatter.Recording.ContainsAnyExcept((byte)0x00)) if (!Chatter.Initialized && !Chatter.Recording.ContainsAnyExcept<byte>(0x00))
return; return;
if (!File.Exists(TempPath))
await File.WriteAllBytesAsync(TempPath, ConvertPCMToWAV(Chatter.Recording)).ConfigureAwait(true); var data = ConvertPCMToWAV(Chatter.Recording);
Sounds.SoundLocation = TempPath; Sounds.Stream = new MemoryStream(data);
try { try
{
Sounds.Play(); Sounds.Play();
} }
catch { Debug.WriteLine("Failed to play sound."); } catch { Debug.WriteLine("Failed to play sound."); }
@ -95,27 +93,22 @@ public partial class SAV_Chatter : Form
{ {
Origin.CopyChangesFrom(SAV); Origin.CopyChangesFrom(SAV);
Sounds.Stop(); Sounds.Stop();
DeleteTempFile();
Close(); Close();
} }
private void B_Cancel_Click(object sender, EventArgs e) private void B_Cancel_Click(object sender, EventArgs e)
{ {
Sounds.Stop(); Sounds.Stop();
DeleteTempFile();
Close(); Close();
} }
private void DeleteTempFile() private static int GetWAVExpectedLength() => WAVHeader.Length + (IChatter.SIZE_PCM * 2);
{
if (!File.Exists(TempPath))
return;
try { File.Delete(TempPath); } /// <summary>
catch (Exception ex) { Debug.WriteLine(ex.Message); } /// Size: 2x <see cref="IChatter.SIZE_PCM"/>"/>
} /// </summary>
private static ReadOnlySpan<byte> WAVHeader =>
private static readonly byte[] WAVHeader = [ [
// RIFF chunk // RIFF chunk
0x52, 0x49, 0x46, 0x46, // chunk name: "RIFF" 0x52, 0x49, 0x46, 0x46, // chunk name: "RIFF"
0xF4, 0x07, 0x00, 0x00, // chunk size: 2036 0xF4, 0x07, 0x00, 0x00, // chunk size: 2036
@ -143,14 +136,19 @@ public partial class SAV_Chatter : Form
/// <returns>WAV file with unsigned 8-bit PCM data</returns> /// <returns>WAV file with unsigned 8-bit PCM data</returns>
private static byte[] ConvertPCMToWAV(ReadOnlySpan<byte> pcm) private static byte[] ConvertPCMToWAV(ReadOnlySpan<byte> pcm)
{ {
byte[] data = new byte[WAVHeader.Length + pcm.Length * 2]; byte[] data = new byte[GetWAVExpectedLength()];
WAVHeader.CopyTo(data, 0); ConvertPCMToWAV(pcm, data);
return data;
}
private static void ConvertPCMToWAV(ReadOnlySpan<byte> pcm, Span<byte> result)
{
WAVHeader.CopyTo(result);
var i = WAVHeader.Length; var i = WAVHeader.Length;
foreach (byte b in pcm) foreach (byte b in pcm)
{ {
data[i++] = (byte)((b & 0x0F) << 4); result[i++] = (byte)((b & 0x0F) << 4);
data[i++] = (byte)(b & 0xF0); result[i++] = (byte)(b & 0xF0);
} }
return data;
} }
} }