mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-04 23:07:46 -04:00
sound, add ym2612 channel clipping, ladder effect
This commit is contained in:
parent
55615f9c97
commit
8794ba5c8d
7 changed files with 39 additions and 9 deletions
|
@ -67,7 +67,9 @@ void PsndRerate(int preserve_state)
|
|||
ym2612_pack_state();
|
||||
memcpy(state, YM2612GetRegs(), 0x204);
|
||||
}
|
||||
YM2612Init(Pico.m.pal ? OSC_PAL/7 : OSC_NTSC/7, PicoIn.sndRate, !(PicoIn.opt&POPT_DIS_FM_SSGEG));
|
||||
YM2612Init(Pico.m.pal ? OSC_PAL/7 : OSC_NTSC/7, PicoIn.sndRate,
|
||||
((PicoIn.opt&POPT_DIS_FM_SSGEG) ? 0 : ST_SSG) |
|
||||
((PicoIn.opt&POPT_EN_FM_LADDER) ? ST_LADDER : 0));
|
||||
if (preserve_state) {
|
||||
// feed it back it's own registers, just like after loading state
|
||||
memcpy(YM2612GetRegs(), state, 0x204);
|
||||
|
|
|
@ -918,6 +918,14 @@ typedef struct
|
|||
|
||||
|
||||
#if !defined(_ASM_YM2612_C) || defined(EXTERNAL_YM2612)
|
||||
#include <limits.h>
|
||||
static int clip(int n)
|
||||
{
|
||||
unsigned b = 14, s = n < 0;
|
||||
if (s + (n>>(b-1))) n = (int)(s + INT_MAX) >> (8*sizeof(int)-b);
|
||||
return n;
|
||||
}
|
||||
|
||||
static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)
|
||||
{
|
||||
int scounter; /* sample counter */
|
||||
|
@ -1226,6 +1234,7 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)
|
|||
|
||||
/* mix sample to output buffer */
|
||||
if (smp) {
|
||||
smp = clip(smp); /* saturate to 14 bit */
|
||||
if (ct->pack & 1) { /* stereo */
|
||||
if (ct->pack & 0x20) /* L */ /* TODO: check correctness */
|
||||
buffer[scounter*2] += smp;
|
||||
|
@ -1256,12 +1265,21 @@ static void chan_render_prep(void)
|
|||
crct.lfo_inc = ym2612.OPN.lfo_inc;
|
||||
}
|
||||
|
||||
static void chan_render_finish(void)
|
||||
static void chan_render_finish(int *buffer, unsigned short length, int active_chans)
|
||||
{
|
||||
ym2612.OPN.eg_cnt = crct.eg_cnt;
|
||||
ym2612.OPN.eg_timer = crct.eg_timer;
|
||||
g_lfo_ampm = crct.pack >> 16; // need_save
|
||||
ym2612.OPN.lfo_cnt = crct.lfo_cnt;
|
||||
|
||||
/* apply ladder effect. NB only works if buffer was empty beforehand! */
|
||||
if (active_chans && (ym2612.OPN.ST.flags & ST_LADDER)) {
|
||||
length <<= crct.pack & 1;
|
||||
while (length--) {
|
||||
*buffer -= (*buffer < 0)*4 << 5;
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static UINT32 update_lfo_phase(FM_SLOT *SLOT, UINT32 block_fnum)
|
||||
|
@ -1835,21 +1853,21 @@ int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty)
|
|||
BIT_IF(flags, 1, (ym2612.ssg_mask & 0xf00000) && (ym2612.OPN.ST.flags & 1));
|
||||
if (ym2612.slot_mask & 0xf00000) active_chs |= chan_render(buffer, length, 5, flags|((pan&0xc00)>>6)|(!!ym2612.dacen<<2)) << 5;
|
||||
#undef BIT_IF
|
||||
chan_render_finish();
|
||||
chan_render_finish(buffer, length, active_chs);
|
||||
|
||||
return active_chs; // 1 if buffer updated
|
||||
}
|
||||
|
||||
|
||||
/* initialize YM2612 emulator */
|
||||
void YM2612Init_(int clock, int rate, int ssg)
|
||||
void YM2612Init_(int clock, int rate, int flags)
|
||||
{
|
||||
memset(&ym2612, 0, sizeof(ym2612));
|
||||
init_tables();
|
||||
|
||||
ym2612.OPN.ST.clock = clock;
|
||||
ym2612.OPN.ST.rate = rate;
|
||||
ym2612.OPN.ST.flags = (ssg ? 1:0);
|
||||
ym2612.OPN.ST.flags = flags;
|
||||
|
||||
OPNSetPres( 6*24 );
|
||||
|
||||
|
|
|
@ -108,6 +108,9 @@ typedef struct
|
|||
INT32 dt_tab[8][32];/* DeTune table */
|
||||
} FM_ST;
|
||||
|
||||
#define ST_SSG 1
|
||||
#define ST_LADDER 2
|
||||
|
||||
/***********************************************************/
|
||||
/* OPN unit */
|
||||
/***********************************************************/
|
||||
|
@ -162,7 +165,7 @@ typedef struct
|
|||
extern YM2612 ym2612;
|
||||
#endif
|
||||
|
||||
void YM2612Init_(int baseclock, int rate, int ssg);
|
||||
void YM2612Init_(int baseclock, int rate, int flags);
|
||||
void YM2612ResetChip_(void);
|
||||
int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty);
|
||||
|
||||
|
@ -184,9 +187,9 @@ int YM2612PicoStateLoad2(int *tat, int *tbt);
|
|||
#else
|
||||
/* GP2X specific */
|
||||
#include <platform/gp2x/940ctl.h>
|
||||
#define YM2612Init(baseclock,rate,ssg) do { \
|
||||
if (PicoIn.opt&POPT_EXT_FM) YM2612Init_940(baseclock, rate, ssg); \
|
||||
else YM2612Init_(baseclock, rate, ssg); \
|
||||
#define YM2612Init(baseclock,rate,flags) do { \
|
||||
if (PicoIn.opt&POPT_EXT_FM) YM2612Init_940(baseclock, rate, flags); \
|
||||
else YM2612Init_(baseclock, rate, flags); \
|
||||
} while (0)
|
||||
#define YM2612ResetChip() do { \
|
||||
if (PicoIn.opt&POPT_EXT_FM) YM2612ResetChip_940(); \
|
||||
|
|
|
@ -924,6 +924,10 @@ crl_algo_done:
|
|||
tst r0, r0
|
||||
beq ctl_sample_skip
|
||||
orr r4, r4, #8 @ have_output
|
||||
lsr r1, r0, #31 @ clip (saturate) sample to 14 bit
|
||||
adds r2, r1, r0, asr #13
|
||||
subne r0, r1, #0x80000001
|
||||
asrne r0, r0, #18
|
||||
tst r12, #1
|
||||
beq ctl_sample_mono
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue