av dumping: hack in a new audio sync method for the dump. doesn't make much of a difference in most stuff. sort of fixes Tsumi to Batsu - Hoshi no Keishousha; but that's mupen's fault anyway

This commit is contained in:
goyuken 2014-10-11 03:33:09 +00:00
parent 1de1e60f49
commit 3eb4dde346
5 changed files with 80 additions and 46 deletions

View File

@ -82,6 +82,9 @@ namespace BizHawk.Client.EmuHawk
s.GetSamples(out samples, out samplesprovided);
exaudio_num += samplesprovided * (long)fpsnum;
// todo: scan for duplicate frames (ie, video content exactly matches previous frame) and for them, skip the threshone step
// this is a good idea, but expensive on time. is it worth it?
if (exaudio_num >= threshone)
{
// add frame once

View File

@ -257,6 +257,11 @@ namespace BizHawk.Client.EmuHawk
{
if (ffmpeg.HasExited)
throw new Exception("unexpected ffmpeg death:\n" + ffmpeg_geterror());
if (samples.Length == 0)
{
// has special meaning for the muxer, so don't pass on
return;
}
try
{
muxer.WriteAudioFrame(samples);

View File

@ -36,13 +36,14 @@
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
this.labelDescription = new System.Windows.Forms.Label();
this.labelDescriptionBody = new System.Windows.Forms.Label();
this.numericTextBoxW = new BizHawk.Client.EmuHawk.NumericTextBox();
this.numericTextBoxH = new BizHawk.Client.EmuHawk.NumericTextBox();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.buttonAuto = new System.Windows.Forms.Button();
this.panelSizeSelect = new System.Windows.Forms.Panel();
this.checkBoxPad = new System.Windows.Forms.CheckBox();
this.numericTextBoxW = new BizHawk.Client.EmuHawk.NumericTextBox();
this.numericTextBoxH = new BizHawk.Client.EmuHawk.NumericTextBox();
this.checkBoxASync = new System.Windows.Forms.CheckBox();
this.tableLayoutPanel4.SuspendLayout();
this.panelSizeSelect.SuspendLayout();
this.SuspendLayout();
@ -130,26 +131,6 @@
this.labelDescriptionBody.TabIndex = 6;
this.labelDescriptionBody.Text = resources.GetString("labelDescriptionBody.Text");
//
// numericTextBoxW
//
this.numericTextBoxW.AllowDecimal = false;
this.numericTextBoxW.AllowNegative = false;
this.numericTextBoxW.AllowSpace = false;
this.numericTextBoxW.Location = new System.Drawing.Point(0, 16);
this.numericTextBoxW.Name = "numericTextBoxW";
this.numericTextBoxW.Size = new System.Drawing.Size(70, 20);
this.numericTextBoxW.TabIndex = 10;
//
// numericTextBoxH
//
this.numericTextBoxH.AllowDecimal = false;
this.numericTextBoxH.AllowNegative = false;
this.numericTextBoxH.AllowSpace = false;
this.numericTextBoxH.Location = new System.Drawing.Point(92, 16);
this.numericTextBoxH.Name = "numericTextBoxH";
this.numericTextBoxH.Size = new System.Drawing.Size(70, 20);
this.numericTextBoxH.TabIndex = 11;
//
// label3
//
this.label3.AutoSize = true;
@ -187,7 +168,7 @@
this.panelSizeSelect.Controls.Add(this.numericTextBoxW);
this.panelSizeSelect.Controls.Add(this.numericTextBoxH);
this.panelSizeSelect.Controls.Add(this.label3);
this.panelSizeSelect.Location = new System.Drawing.Point(347, 35);
this.panelSizeSelect.Location = new System.Drawing.Point(347, 58);
this.panelSizeSelect.Name = "panelSizeSelect";
this.panelSizeSelect.Size = new System.Drawing.Size(162, 105);
this.panelSizeSelect.TabIndex = 15;
@ -202,6 +183,36 @@
this.checkBoxPad.Text = "Pad";
this.checkBoxPad.UseVisualStyleBackColor = true;
//
// numericTextBoxW
//
this.numericTextBoxW.AllowDecimal = false;
this.numericTextBoxW.AllowNegative = false;
this.numericTextBoxW.AllowSpace = false;
this.numericTextBoxW.Location = new System.Drawing.Point(0, 16);
this.numericTextBoxW.Name = "numericTextBoxW";
this.numericTextBoxW.Size = new System.Drawing.Size(70, 20);
this.numericTextBoxW.TabIndex = 10;
//
// numericTextBoxH
//
this.numericTextBoxH.AllowDecimal = false;
this.numericTextBoxH.AllowNegative = false;
this.numericTextBoxH.AllowSpace = false;
this.numericTextBoxH.Location = new System.Drawing.Point(92, 16);
this.numericTextBoxH.Name = "numericTextBoxH";
this.numericTextBoxH.Size = new System.Drawing.Size(70, 20);
this.numericTextBoxH.TabIndex = 11;
//
// checkBoxASync
//
this.checkBoxASync.AutoSize = true;
this.checkBoxASync.Location = new System.Drawing.Point(347, 35);
this.checkBoxASync.Name = "checkBoxASync";
this.checkBoxASync.Size = new System.Drawing.Size(95, 17);
this.checkBoxASync.TabIndex = 16;
this.checkBoxASync.Text = "Alternate Sync";
this.checkBoxASync.UseVisualStyleBackColor = true;
//
// VideoWriterChooserForm
//
this.AcceptButton = this.buttonOK;
@ -209,6 +220,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.buttonCancel;
this.ClientSize = new System.Drawing.Size(521, 440);
this.Controls.Add(this.checkBoxASync);
this.Controls.Add(this.panelSizeSelect);
this.Controls.Add(this.tableLayoutPanel4);
this.Controls.Add(this.listBox1);
@ -244,5 +256,6 @@
private System.Windows.Forms.Button buttonAuto;
private System.Windows.Forms.Panel panelSizeSelect;
private System.Windows.Forms.CheckBox checkBoxPad;
private System.Windows.Forms.CheckBox checkBoxASync;
}
}

View File

@ -27,7 +27,7 @@ namespace BizHawk.Client.EmuHawk
/// <param name="list">list of IVideoWriters to choose from</param>
/// <param name="owner">parent window</param>
/// <returns>user choice, or null on Cancel\Close\invalid</returns>
public static IVideoWriter DoVideoWriterChoserDlg(IEnumerable<VideoWriterInfo> list, IWin32Window owner, out int resizew, out int resizeh, out bool pad)
public static IVideoWriter DoVideoWriterChoserDlg(IEnumerable<VideoWriterInfo> list, IWin32Window owner, out int resizew, out int resizeh, out bool pad, out bool audiosync)
{
VideoWriterChooserForm dlg = new VideoWriterChooserForm();
@ -78,6 +78,7 @@ namespace BizHawk.Client.EmuHawk
}
pad = dlg.checkBoxPad.Checked;
audiosync = dlg.checkBoxASync.Checked;
dlg.Dispose();
return ret;

View File

@ -1204,7 +1204,7 @@ namespace BizHawk.Client.EmuHawk
private IVideoWriter _currAviWriter;
private ISoundProvider _aviSoundInput;
private MetaspuSoundProvider _dumpProxy; // an audio proxy used for dumping
private long _soundRemainder; // audio timekeeping for video dumping
private bool _dumpaudiosync; // set true to for experimental AV dumping
private int _avwriterResizew;
private int _avwriterResizeh;
private bool _avwriterpad;
@ -2790,7 +2790,8 @@ namespace BizHawk.Client.EmuHawk
}
else
{
aw = VideoWriterChooserForm.DoVideoWriterChoserDlg(VideoWriterInventory.GetAllWriters(), GlobalWin.MainForm, out _avwriterResizew, out _avwriterResizeh, out _avwriterpad);
aw = VideoWriterChooserForm.DoVideoWriterChoserDlg(VideoWriterInventory.GetAllWriters(), this,
out _avwriterResizew, out _avwriterResizeh, out _avwriterpad, out _dumpaudiosync);
}
if (aw == null)
@ -2803,6 +2804,15 @@ namespace BizHawk.Client.EmuHawk
try
{
if (_dumpaudiosync)
{
aw = new VideoStretcher(aw);
}
else
{
aw = new AudioStretcher(aw);
}
aw.SetMovieParameters(Global.Emulator.CoreComm.VsyncNum, Global.Emulator.CoreComm.VsyncDen);
if (_avwriterResizew > 0 && _avwriterResizeh > 0)
{
@ -2898,13 +2908,17 @@ namespace BizHawk.Client.EmuHawk
throw;
}
// do sound rewire. the plan is to eventually have AVI writing support syncsound input, but it doesn't for the moment
_aviSoundInput = !Global.Emulator.StartAsyncSound()
? new MetaspuAsync(Global.Emulator.SyncSoundProvider, ESynchMethod.ESynchMethod_V)
: Global.Emulator.SoundProvider;
if (_dumpaudiosync)
{
Global.Emulator.EndAsyncSound();
}
else
{
_aviSoundInput = !Global.Emulator.StartAsyncSound()
? new MetaspuAsync(Global.Emulator.SyncSoundProvider, ESynchMethod.ESynchMethod_V)
: Global.Emulator.SoundProvider;
}
_dumpProxy = new MetaspuSoundProvider(ESynchMethod.ESynchMethod_V);
_soundRemainder = 0;
RewireSound();
}
@ -2925,7 +2939,6 @@ namespace BizHawk.Client.EmuHawk
AVIStatusLabel.Visible = false;
_aviSoundInput = null;
_dumpProxy = null; // return to normal sound output
_soundRemainder = 0;
RewireSound();
}
@ -2947,7 +2960,6 @@ namespace BizHawk.Client.EmuHawk
AVIStatusLabel.Visible = false;
_aviSoundInput = null;
_dumpProxy = null; // return to normal sound output
_soundRemainder = 0;
RewireSound();
}
@ -2956,16 +2968,6 @@ namespace BizHawk.Client.EmuHawk
GlobalWin.DisplayManager.NeedsToPaint = true;
if (_currAviWriter != null)
{
var nsampnum = 44100 * (long)Global.Emulator.CoreComm.VsyncDen + _soundRemainder;
var nsamp = nsampnum / Global.Emulator.CoreComm.VsyncNum;
// exactly remember fractional parts of an audio sample
_soundRemainder = nsampnum % Global.Emulator.CoreComm.VsyncNum;
var temp = new short[nsamp * 2];
_aviSoundInput.GetSamples(temp);
_dumpProxy.buffer.enqueue_samples(temp, (int)nsamp);
//TODO ZERO - this code is pretty jacked. we'll want to frugalize buffers better for speedier dumping, and we might want to rely on the GL layer for padding
try
{
@ -3024,14 +3026,24 @@ namespace BizHawk.Client.EmuHawk
}
_currAviWriter.SetFrame(Global.Emulator.Frame);
_currAviWriter.AddFrame(output);
short[] samp;
int nsamp;
if (_dumpaudiosync)
{
(_currAviWriter as VideoStretcher).DumpAV(output, Global.Emulator.SyncSoundProvider, out samp, out nsamp);
}
else
{
(_currAviWriter as AudioStretcher).DumpAV(output, _aviSoundInput, out samp, out nsamp);
}
if (disposableOutput != null)
{
disposableOutput.Dispose();
}
_currAviWriter.AddSamples(temp);
_dumpProxy.buffer.enqueue_samples(samp, nsamp);
}
catch (Exception e)
{