Skip to content

Commit

Permalink
implement #102 MSX-MUSIC YM2413 emulation using NukeYKT's OPLL
Browse files Browse the repository at this point in the history
  • Loading branch information
cayce-msx committed Feb 7, 2024
1 parent fa36444 commit bd7a18f
Show file tree
Hide file tree
Showing 13 changed files with 1,930 additions and 42 deletions.
9 changes: 3 additions & 6 deletions EMULib/EMULib.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,10 @@
/** Sound ****************************************************/
// fMSX emulates:
// - AY8910 PSG: 3 melodic + 3 noise
// - YM2413 OPLL: 9 FM sound channels, or 6 music + 5 drums
// - YM2413 OPLL: 9 FM sound channels (or 6 music + 5 drums, but fMSX does not emulate drums)
// - SCC: 5 wave channels
// fMSX does not support FM-PAC drums nor instruments (uses triangle waves), and plays either FM-PAC or SCC.
// Thus: either 15, 12 or 11 channels active at once.
#define SND_CHANNELS 16 /* Number of sound channels */
#define SND_BITS 8
#define SND_BUFSIZE (1<<SND_BITS)
// Thus: max 20 channels active at once.
#define SND_CHANNELS 20 /* Number of sound channels */

#ifdef __cplusplus
extern "C" {
Expand Down
46 changes: 43 additions & 3 deletions EMULib/Sound.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
/** changes to this file. **/
/*************************************************************/
#include "Sound.h"
#include "MSX.h"

#include "../NukeYKT/WrapNukeYKT.h"

#include <string.h>

Expand Down Expand Up @@ -52,6 +55,10 @@ static struct
{ SND_MELODIC,0,0,0,0,0,0,0 },
{ SND_MELODIC,0,0,0,0,0,0,0 },
{ SND_MELODIC,0,0,0,0,0,0,0 },
{ SND_MELODIC,0,0,0,0,0,0,0 },
{ SND_MELODIC,0,0,0,0,0,0,0 },
{ SND_MELODIC,0,0,0,0,0,0,0 },
{ SND_MELODIC,0,0,0,0,0,0,0 },
{ SND_MELODIC,0,0,0,0,0,0,0 }
};

Expand All @@ -63,6 +70,9 @@ static int NoiseXor = 14; /* NoiseGen bit used for XORing */
int MasterSwitch = 0xFFFF; /* Switches to turn channels on/off */
int MasterVolume = 192; /* Master volume */

extern YM2413_NukeYKT OPLL_NukeYKT;
extern YM2413 OPLL;

/** Sound() **************************************************/
/** Generate sound of given frequency (Hz) and volume **/
/** (0..255) via given channel. Setting Freq=0 or Volume=0 **/
Expand Down Expand Up @@ -358,24 +368,54 @@ static unsigned int PlayAudio(int *Wave,unsigned int Samples)
unsigned int RenderAndPlayAudio(unsigned int Samples)
{
int Buf[256];
unsigned int J,I;
unsigned int J,I,K,idx;
float ResampleRate,R,frac;

/* Exit if wave sound not initialized */
if(SndRate<8192) return(0);

/* silence fMSX FM-PAC if NukeYKT is active */
if(OPTION(MSX_NUKEYKT))
{
for(K=0;K<YM2413_CHANNELS;K++)
Sound(K+OPLL.First,0,0);
OPLL.Changed=0;
}

J = AUDIO_BUFFER_SIZE;
Samples = Samples<J? Samples:J;

ResampleRate = (float)OPLL_NukeYKT.sample_write_index/Samples;

/* Render and play sound */
for(I=0;I<Samples;I+=J)
for(I=0,R=0.0;I<Samples;I+=J)
{
J = Samples-I;
J = J<sizeof(Buf)/sizeof(Buf[0])? J:sizeof(Buf)/sizeof(Buf[0]);
memset(Buf,0,J*sizeof(Buf[0]));
RenderAudio(Buf,J);

/*
* Merge in YM2413 NukeYKT using simplistic linear resampler.
* Max input range slightly outside [-1024,+1023], output [-32768,+32767] or 16b signed after amplification by 32.
* BUT matching it to PSG volume (by hand) requires a further amplification by 4.
* That's still a factor 4-8 less loud than fMSX's FM-PAC volume.
*/
if(OPTION(MSX_NUKEYKT))
for(K=0;K<J;K++,R+=ResampleRate)
{
idx=(unsigned int)R;
frac=R-idx;
Buf[K]+=(int)(.5+128.0*(OPLL_NukeYKT.samples[idx]*(1.0-frac) + OPLL_NukeYKT.samples[idx+1]*frac));
}

if(PlayAudio(Buf,J)<J) { I+=J;break; }
}

// move last sample to beginning (for linear resampler) and signal a buffer refill
if (OPLL_NukeYKT.sample_write_index>0)
OPLL_NukeYKT.samples[0]=OPLL_NukeYKT.samples[OPLL_NukeYKT.sample_write_index-1];
OPLL_NukeYKT.sample_write_index=1;

/* Return number of samples rendered */
return I;
}
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ CORE_DIR = .
EMULIB = $(CORE_DIR)/EMULib
FMSXDIR = $(CORE_DIR)/fMSX
LIBZ80 = $(CORE_DIR)/Z80
NUKEYKT = $(CORE_DIR)/NukeYKT

include Makefile.common

Expand Down
4 changes: 3 additions & 1 deletion Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ SOURCES_C := \
$(EMULIB)/YM2413.c \
$(EMULIB)/AY8910.c \
$(EMULIB)/SCC.c \
$(EMULIB)/WD1793.c
$(EMULIB)/WD1793.c \
$(NUKEYKT)/opll.c \
$(NUKEYKT)/WrapNukeYKT.c

ifneq ($(STATIC_LINKING), 1)
SOURCES_C += $(CORE_DIR)/libretro-common/file/retro_dirent.c \
Expand Down
Loading

0 comments on commit bd7a18f

Please sign in to comment.