MSXHawk: Audio
This commit is contained in:
parent
80f363196a
commit
eaf8e52746
|
@ -46,14 +46,21 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
/// Get Video data
|
||||
/// </summary>
|
||||
/// <param name="core">opaque state pointer</param>
|
||||
/// <param name="ctrl1">controller data for player 1</param>
|
||||
/// <param name="ctrl2">controller data for player 2</param>
|
||||
/// <param name="render">length of romdata in bytes</param>
|
||||
/// <param name="sound">Mapper number to load core with</param>
|
||||
/// <returns>0 on success, negative value on failure.</returns>
|
||||
/// <param name="videobuf">where to send video to</param>
|
||||
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void MSX_get_video(IntPtr core, int[] videobuf);
|
||||
|
||||
/// <summary>
|
||||
/// Get Video data
|
||||
/// </summary>
|
||||
/// <param name="core">opaque state pointer</param>
|
||||
/// <param name="aud_buf_L">where to send left audio to</param>
|
||||
/// <param name="aud_buf_R">where to send right audio to</param>
|
||||
/// <param name="n_samp_L">number of left samples</param>
|
||||
/// <param name="n_samp_R">number of right samples</param>
|
||||
[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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<MSX.MSXSettings, MSX.MSXSyncSettings>
|
||||
public partial class MSX : IEmulator, IVideoProvider, ISoundProvider, ISaveRam, IStatable, IInputPollable, IRegionable, ISettable<MSX.MSXSettings, MSX.MSXSyncSettings>
|
||||
{
|
||||
[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() };
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue