diff --git a/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs b/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
index b11b63f292..b03586b41b 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
@@ -46,14 +46,21 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
/// Get Video data
///
/// opaque state pointer
- /// controller data for player 1
- /// controller data for player 2
- /// length of romdata in bytes
- /// Mapper number to load core with
- /// 0 on success, negative value on failure.
+ /// where to send video to
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void MSX_get_video(IntPtr core, int[] videobuf);
+ ///
+ /// Get Video data
+ ///
+ /// opaque state pointer
+ /// where to send left audio to
+ /// where to send right audio to
+ /// number of left samples
+ /// number of right samples
+ [DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
+ public static extern uint MSX_get_audio(IntPtr core, uint[] aud_buf_L, uint[] aud_buf_R, ref uint n_samp_L, ref uint n_samp_R);
+
#endregion
#region Memory Domain Functions
diff --git a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
index dcf2e50b35..be091dfe4b 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
@@ -15,9 +15,6 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
}
}
- // not savestated variables
- int s_L, s_R;
-
public bool FrameAdvance(IController controller, bool render, bool rendersound)
{
_controller = controller;
@@ -78,13 +75,14 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
#region Audio
- public BlipBuffer blip_L = new BlipBuffer(4096);
- public BlipBuffer blip_R = new BlipBuffer(4096);
- const int blipbuffsize = 4096;
+ public BlipBuffer blip_L = new BlipBuffer(4500);
+ public BlipBuffer blip_R = new BlipBuffer(4500);
- public uint sampleclock;
- public int old_s_L = 0;
- public int old_s_R = 0;
+ public uint[] Aud_L = new uint [9000];
+ public uint[] Aud_R = new uint[9000];
+ public uint num_samp_L, num_samp_R;
+
+ const int blipbuffsize = 4500;
public bool CanProvideAsync { get { return false; } }
@@ -108,23 +106,32 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
public void GetSamplesSync(out short[] samples, out int nsamp)
{
- blip_L.EndFrame(sampleclock);
- blip_R.EndFrame(sampleclock);
+ uint f_clock = LibMSX.MSX_get_audio(MSX_Pntr, Aud_L, Aud_R, ref num_samp_L, ref num_samp_R);
+
+ for (int i = 0; i < num_samp_L;i++)
+ {
+ blip_L.AddDelta(Aud_L[i * 2], (int)Aud_L[i * 2 + 1]);
+ }
+
+ for (int i = 0; i < num_samp_R; i++)
+ {
+ blip_R.AddDelta(Aud_R[i * 2], (int)Aud_R[i * 2 + 1]);
+ }
+
+ blip_L.EndFrame(f_clock);
+ blip_R.EndFrame(f_clock);
nsamp = Math.Max(Math.Max(blip_L.SamplesAvailable(), blip_R.SamplesAvailable()), 1);
samples = new short[nsamp * 2];
blip_L.ReadSamplesLeft(samples, nsamp);
blip_R.ReadSamplesRight(samples, nsamp);
-
- sampleclock = 0;
}
public void DiscardSamples()
{
blip_L.Clear();
blip_R.Clear();
- sampleclock = 0;
}
#endregion
diff --git a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IStatable.cs b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IStatable.cs
index 463167b7ad..06a3f664b0 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IStatable.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IStatable.cs
@@ -50,10 +50,6 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
ser.BeginSection("MSX");
- ser.Sync(nameof(sampleclock), ref sampleclock);
- ser.Sync(nameof(old_s_L), ref old_s_L);
- ser.Sync(nameof(old_s_R), ref old_s_R);
-
if (SaveRAM != null)
{
ser.Sync(nameof(SaveRAM), ref SaveRAM, false);
diff --git a/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs b/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs
index 74e64e6089..83216bbd44 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs
@@ -10,7 +10,7 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
isPorted: false,
isReleased: false)]
[ServiceNotApplicable(typeof(IDriveLight))]
- public partial class MSX : IEmulator, IVideoProvider, ISaveRam, IStatable, IInputPollable, IRegionable, ISettable
+ public partial class MSX : IEmulator, IVideoProvider, ISoundProvider, ISaveRam, IStatable, IInputPollable, IRegionable, ISettable
{
[CoreConstructor("MSX")]
public MSX(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings)
@@ -46,8 +46,6 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
StringBuilder new_header = new StringBuilder(Header_Length);
LibMSX.MSX_getheader(MSX_Pntr, new_header, Header_Length);
-
-
Console.WriteLine(Header_Length + " " + Disasm_Length + " " + Reg_String_Length);
Tracer = new TraceBuffer { Header = new_header.ToString() };
diff --git a/libHawk/MSXHawk/MSXHawk/Core.h b/libHawk/MSXHawk/MSXHawk/Core.h
index d590d9377b..8a4d4ecaec 100644
--- a/libHawk/MSXHawk/MSXHawk/Core.h
+++ b/libHawk/MSXHawk/MSXHawk/Core.h
@@ -41,6 +41,11 @@ namespace MSXHawk
int scanlinesPerFrame = 262;
vdp.SpriteLimit = true;
+
+ psg.num_samples_L = 0;
+ psg.num_samples_R = 0;
+ psg.sampleclock = 0;
+
for (int i = 0; i < scanlinesPerFrame; i++)
{
vdp.ScanLine = i;
@@ -55,24 +60,6 @@ namespace MSXHawk
cpu.ExecuteOne();
psg.generate_sound();
- /*
- s_L = psg.current_sample_L;
- s_R = psg.current_sample_R;
-
- if (s_L != old_s_L)
- {
- blip_L.AddDelta(sampleclock, s_L - old_s_L);
- old_s_L = s_L;
- }
-
- if (s_R != old_s_R)
- {
- blip_R.AddDelta(sampleclock, s_R - old_s_R);
- old_s_R = s_R;
- }
-
- sampleclock++;
- */
}
if (vdp.ScanLine == scanlinesPerFrame - 1)
@@ -81,11 +68,7 @@ namespace MSXHawk
//vdp.ProcessOverscan();
}
}
- /*
- while (cpu.TotalExecutedCycles < 211936) {
- cpu.ExecuteOne();
- }
- */
+
return MemMap.lagged;
}
@@ -101,6 +84,23 @@ namespace MSXHawk
}
}
+ uint32_t GetAudio(uint32_t* dest_L, uint32_t* dest_R, uint32_t* n_samp_L, uint32_t* n_samp_R)
+ {
+ uint32_t* src_L = psg.samples_L;
+ uint32_t* dst_L = dest_L;
+
+ std::memcpy(dst_L, src_L, sizeof uint32_t * psg.num_samples_L * 2);
+ n_samp_L[0] = psg.num_samples_L;
+
+ uint32_t* src_R = psg.samples_R;
+ uint32_t* dst_R = dest_R;
+
+ std::memcpy(dst_R, src_R, sizeof uint32_t * psg.num_samples_R * 2);
+ n_samp_R[0] = psg.num_samples_R;
+
+ return psg.sampleclock;
+ }
+
#pragma region Memory Domain Functions
uint8_t GetSysBus(uint32_t addr)
diff --git a/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp b/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
index 6d9cb22c9e..8480c4f676 100644
--- a/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
+++ b/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
@@ -42,10 +42,12 @@ MSXHAWK_EXPORT void MSX_get_video(MSXCore* p, uint32_t* dest)
p->GetVideo(dest);
}
-// set tracer callback
-MSXHAWK_EXPORT void MSX_settracecallback(MSXCore* p, void (*callback)(int)) {
- p->SetTraceCallback(callback);
+// send audio data to external audio provider
+MSXHAWK_EXPORT uint32_t MSX_get_audio(MSXCore* p, uint32_t* dest_L, uint32_t* dest_R, uint32_t* n_samp_L, uint32_t* n_samp_R)
+{
+ return p->GetAudio(dest_L, dest_R, n_samp_L, n_samp_R);
}
+
#pragma endregion
#pragma region Memory Domain Functions
@@ -62,6 +64,11 @@ MSXHAWK_EXPORT uint8_t MSX_getvram(MSXCore* p, uint32_t addr) {
#pragma region Tracer
+// set tracer callback
+MSXHAWK_EXPORT void MSX_settracecallback(MSXCore* p, void (*callback)(int)) {
+ p->SetTraceCallback(callback);
+}
+
// return the cpu trace header length
MSXHAWK_EXPORT int MSX_getheaderlength(MSXCore* p) {
return p->GetHeaderLength();
diff --git a/libHawk/MSXHawk/MSXHawk/PSG.h b/libHawk/MSXHawk/MSXHawk/PSG.h
index c0c6f5fc30..9dbedcef63 100644
--- a/libHawk/MSXHawk/MSXHawk/PSG.h
+++ b/libHawk/MSXHawk/MSXHawk/PSG.h
@@ -12,6 +12,13 @@ namespace MSXHawk
public:
uint32_t current_sample_L;
uint32_t current_sample_R;
+ uint32_t old_sample_L;
+ uint32_t old_sample_R;
+ uint32_t sampleclock;
+ uint32_t num_samples_L;
+ uint32_t num_samples_R;
+ uint32_t samples_L[9000] = {};
+ uint32_t samples_R[9000] = {};
SN76489sms()
{
@@ -256,7 +263,25 @@ namespace MSXHawk
current_sample_R += (C_R ? (C_up ? LogScale[Chan_vol[2]] * 42 : 0) : 0);
current_sample_R += (noise_R ? (noise_bit ? LogScale[Chan_vol[3]] * 42 : 0) : 0);
+
+ if ((current_sample_L != old_sample_L) && (num_samples_L < 4500))
+ {
+ samples_L[num_samples_L * 2] = sampleclock;
+ samples_L[num_samples_L * 2 + 1] = current_sample_L - old_sample_L;
+ num_samples_L++;
+ old_sample_L = current_sample_L;
+ }
+
+ if ((current_sample_R != old_sample_R) && (num_samples_R < 4500))
+ {
+ samples_R[num_samples_R * 2] = sampleclock;
+ samples_R[num_samples_R * 2 + 1] = current_sample_R - old_sample_R;
+ num_samples_R++;
+ old_sample_R = current_sample_R;
+ }
}
+
+ sampleclock++;
}
};
}
\ No newline at end of file