From 6f1bb8999b1c05ea44f507791b34d3d0fde738ba Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Wed, 20 Apr 2011 11:02:59 +0300 Subject: [PATCH] Streamtools: Support multichannel FM Support converting dumps containing multiple FM streams without corrupting the stream (mix the converted PCM streams, not the raw FM data). --- streamtools/Makefile | 4 +- streamtools/opl.cpp | 952 ++++++++++++++++++++-------------------------- streamtools/opl.h | 121 +++--- streamtools/resampler.cpp | 8 +- streamtools/resampler.hpp | 3 + 5 files changed, 497 insertions(+), 591 deletions(-) diff --git a/streamtools/Makefile b/streamtools/Makefile index 4b0674f..013d7e8 100644 --- a/streamtools/Makefile +++ b/streamtools/Makefile @@ -1,7 +1,7 @@ all: screenshot.exe dumppackets.exe picturestodump.exe audiotodump.exe demuxdump.exe muxdump.exe mknulldump.exe cutdump.exe fmtopcm.exe playdump.exe dumpconvert.exe guessresolution.exe testresizer.exe COMPILER=g++ -CXXFLAGS=-g -O2 -Wall -I. -std=c++0x +CXXFLAGS=-g -O2 -Wall -I. -std=c++0x -mno-mmx CXXFLAGS2=$(CXXFLAGS) -Werror RESIZE_DRIVERS=resize.o $(patsubst %.cpp,%.o,$(wildcard rescalers/*.cpp)) dynamic/dynamic.o OUTPUT_DRIVERS=rgbtorgb.o $(RESIZE_DRIVERS) dedup.o $(patsubst %.cpp,%.o,$(wildcard outputs/*.cpp)) @@ -59,7 +59,7 @@ rgbtorgb.o: rgbtorgb.cc lanczos.hh rgbtorgb.hh quantize.hh simd.hh $(COMPILER) $(CXXFLAGS2) -Werror -c -o $@ $< `sdl-config --cflags` opl.o: opl.cpp opl.h - $(COMPILER) $(CXXFLAGS2) -DINLINE=inline -DOPLTYPE_IS_OPL3 -DOPL_CPP -c -o $@ $< + $(COMPILER) $(CXXFLAGS2) -DOPL_INLINE=inline -c -o $@ $< testresizer.exe: testresizer.o $(RESIZE_DRIVERS) main.o $(COMPILER) $(CXXFLAGS2) -o $@ $^ $(LIBS) diff --git a/streamtools/opl.cpp b/streamtools/opl.cpp index af2cf24..0d949fd 100644 --- a/streamtools/opl.cpp +++ b/streamtools/opl.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2002-2009 The DOSBox Team + * Copyright (C) 2011 H. Ilari Liusvaara * OPL2/OPL3 emulation library * * This library is free software; you can redistribute it and/or @@ -24,34 +25,21 @@ * Ken Silverman's official web site: "http://www.advsys.net/ken" */ +/* + * Modified 20th April 2011 by Ilari: + * - Replace static state with context. + * - Remove OPL2 support (OPL3 is superset anyway) + */ + +#ifndef OPL_INLINE +#define OPL_INLINE +#endif #include #include // rand() #include #include "opl.h" - -static fltype recipsamp; // inverse of sampling rate -static Bit16s wavtable[WAVEPREC*3]; // wave form table - -// vibrato/tremolo tables -static Bit32s vib_table[VIBTAB_SIZE]; -static Bit32s trem_table[TREMTAB_SIZE*2]; - -static Bit32s vibval_const[BLOCKBUF_SIZE]; -static Bit32s tremval_const[BLOCKBUF_SIZE]; - -// vibrato value tables (used per-operator) -static Bit32s vibval_var1[BLOCKBUF_SIZE]; -static Bit32s vibval_var2[BLOCKBUF_SIZE]; -//static Bit32s vibval_var3[BLOCKBUF_SIZE]; -//static Bit32s vibval_var4[BLOCKBUF_SIZE]; - -// vibrato/trmolo value table pointers -static Bit32s *vibval1, *vibval2, *vibval3, *vibval4; -static Bit32s *tremval1, *tremval2, *tremval3, *tremval4; - - // key scale level lookup table static const fltype kslmul[4] = { 0.0, 0.5, 0.25, 1.0 // -> 0, 3, 1.5, 6 dB/oct @@ -61,11 +49,6 @@ static const fltype kslmul[4] = { static const fltype frqmul_tab[16] = { 0.5,1,2,3,4,5,6,7,8,9,10,10,12,12,15,15 }; -// calculated frequency multiplication values (depend on sampling rate) -static float frqmul[16]; - -// key scale levels -static Bit8u kslev[8][16]; // map a channel number to the register offset of the modulator (=register base) static const Bit8u modulatorbase[9] = { @@ -75,7 +58,6 @@ static const Bit8u modulatorbase[9] = { }; // map a register base to a modulator operator number or operator number -#if defined(OPLTYPE_IS_OPL3) static const Bit8u regbase2modop[44] = { 0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8, // first set 18,19,20,18,19,20,0,0,21,22,23,21,22,23,0,0,24,25,26,24,25,26 // second set @@ -84,15 +66,6 @@ static const Bit8u regbase2op[44] = { 0,1,2,9,10,11,0,0,3,4,5,12,13,14,0,0,6,7,8,15,16,17, // first set 18,19,20,27,28,29,0,0,21,22,23,30,31,32,0,0,24,25,26,33,34,35 // second set }; -#else -static const Bit8u regbase2modop[22] = { - 0,1,2,0,1,2,0,0,3,4,5,3,4,5,0,0,6,7,8,6,7,8 -}; -static const Bit8u regbase2op[22] = { - 0,1,2,9,10,11,0,0,3,4,5,12,13,14,0,0,6,7,8,15,16,17 -}; -#endif - // start of the waveform static Bit32u waveform[8] = { @@ -145,17 +118,17 @@ static fltype decrelconst[4] = { }; -void operator_advance(op_type* op_pt, Bit32s vib) { +void operator_advance(opl_context* ctx, op_type* op_pt, Bit32s vib) { op_pt->wfpos = op_pt->tcount; // waveform position // advance waveform time op_pt->tcount += op_pt->tinc; op_pt->tcount += (Bit32s)(op_pt->tinc)*vib/FIXEDPT; - op_pt->generator_pos += generator_add; + op_pt->generator_pos += (ctx->generator_add); } -void operator_advance_drums(op_type* op_pt1, Bit32s vib1, op_type* op_pt2, Bit32s vib2, op_type* op_pt3, Bit32s vib3) { +void operator_advance_drums(opl_context* ctx, op_type* op_pt1, Bit32s vib1, op_type* op_pt2, Bit32s vib2, op_type* op_pt3, Bit32s vib3) { Bit32u c1 = op_pt1->tcount/FIXEDPT; Bit32u c3 = op_pt3->tcount/FIXEDPT; Bit32u phasebit = (((c1 & 0x88) ^ ((c1<<5) & 0x80)) | ((c3 ^ (c3<<2)) & 0x20)) ? 0x02 : 0x00; @@ -170,7 +143,7 @@ void operator_advance_drums(op_type* op_pt1, Bit32s vib1, op_type* op_pt2, Bit32 // advance waveform time op_pt1->tcount += op_pt1->tinc; op_pt1->tcount += (Bit32s)(op_pt1->tinc)*vib1/FIXEDPT; - op_pt1->generator_pos += generator_add; + op_pt1->generator_pos += (ctx->generator_add); //Snare inttm = ((1+snare_phase_bit) ^ noisebit)<<8; @@ -178,7 +151,7 @@ void operator_advance_drums(op_type* op_pt1, Bit32s vib1, op_type* op_pt2, Bit32 // advance waveform time op_pt2->tcount += op_pt2->tinc; op_pt2->tcount += (Bit32s)(op_pt2->tinc)*vib2/FIXEDPT; - op_pt2->generator_pos += generator_add; + op_pt2->generator_pos += (ctx->generator_add); //Cymbal inttm = (1+phasebit)<<8; @@ -186,13 +159,13 @@ void operator_advance_drums(op_type* op_pt1, Bit32s vib1, op_type* op_pt2, Bit32 // advance waveform time op_pt3->tcount += op_pt3->tinc; op_pt3->tcount += (Bit32s)(op_pt3->tinc)*vib3/FIXEDPT; - op_pt3->generator_pos += generator_add; + op_pt3->generator_pos += (ctx->generator_add); } // output level is sustained, mode changes only when operator is turned off (->release) // or when the keep-sustained bit is turned off (->sustain_nokeep) -void operator_output(op_type* op_pt, Bit32s modulator, Bit32s trem) { +void operator_output(opl_context* ctx, op_type* op_pt, Bit32s modulator, Bit32s trem) { if (op_pt->op_state != OF_TYPE_OFF) { op_pt->lastcval = op_pt->cval; Bit32u i = (Bit32u)((op_pt->wfpos+modulator)/FIXEDPT); @@ -208,12 +181,12 @@ void operator_output(op_type* op_pt, Bit32s modulator, Bit32s trem) { // no action, operator is off -void operator_off(op_type* /*op_pt*/) { +void operator_off(opl_context* ctx, op_type* /*op_pt*/) { } // output level is sustained, mode changes only when operator is turned off (->release) // or when the keep-sustained bit is turned off (->sustain_nokeep) -void operator_sustain(op_type* op_pt) { +void operator_sustain(opl_context* ctx, op_type* op_pt) { Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples for (Bit32u ct=0; ctcur_env_step++; @@ -222,7 +195,7 @@ void operator_sustain(op_type* op_pt) { } // operator in release mode, if output level reaches zero the operator is turned off -void operator_release(op_type* op_pt) { +void operator_release(opl_context* ctx, op_type* op_pt) { // ??? boundary? if (op_pt->amp > 0.00000001) { // release phase @@ -248,7 +221,7 @@ void operator_release(op_type* op_pt) { // operator in decay mode, if sustain level is reached the output level is either // kept (sustain level keep enabled) or the operator is switched into release mode -void operator_decay(op_type* op_pt) { +void operator_decay(opl_context* ctx, op_type* op_pt) { if (op_pt->amp > op_pt->sustain_level) { // decay phase op_pt->amp *= op_pt->decaymul; @@ -277,7 +250,7 @@ void operator_decay(op_type* op_pt) { // operator in attack mode, if full output level is reached, // the operator is switched into decay mode -void operator_attack(op_type* op_pt) { +void operator_attack(opl_context* ctx, op_type* op_pt) { op_pt->amp = ((op_pt->a3*op_pt->amp + op_pt->a2)*op_pt->amp + op_pt->a1)*op_pt->amp + op_pt->a0; Bit32u num_steps_add = op_pt->generator_pos/FIXEDPT; // number of (standardized) samples @@ -301,7 +274,7 @@ void operator_attack(op_type* op_pt) { } -typedef void (*optype_fptr)(op_type*); +typedef void (*optype_fptr)(opl_context* ctx, op_type*); optype_fptr opfuncs[6] = { operator_attack, @@ -312,10 +285,10 @@ optype_fptr opfuncs[6] = { operator_off }; -void change_attackrate(Bitu regbase, op_type* op_pt) { - Bits attackrate = adlibreg[ARC_ATTR_DECR+regbase]>>4; +void change_attackrate(opl_context* ctx, Bitu regbase, op_type* op_pt) { + Bits attackrate = (ctx->adlibreg)[ARC_ATTR_DECR+regbase]>>4; if (attackrate) { - fltype f = (fltype)(pow(FL2,(fltype)attackrate+(op_pt->toff>>2)-1)*attackconst[op_pt->toff&3]*recipsamp); + fltype f = (fltype)(pow(FL2,(fltype)attackrate+(op_pt->toff>>2)-1)*attackconst[op_pt->toff&3]*(ctx->recipsamp)); // attack rate coefficients op_pt->a0 = (fltype)(0.0377*f); op_pt->a1 = (fltype)(10.73*f+1); @@ -330,11 +303,7 @@ void change_attackrate(Bitu regbase, op_type* op_pt) { static Bit8u step_skip_mask[5] = {0xff, 0xfe, 0xee, 0xba, 0xaa}; op_pt->env_step_skip_a = step_skip_mask[step_num]; -#if defined(OPLTYPE_IS_OPL3) if (step_skip>=60) { -#else - if (step_skip>=62) { -#endif op_pt->a0 = (fltype)(2.0); // something that triggers an immediate transition to amp:=1.0 op_pt->a1 = (fltype)(0.0); op_pt->a2 = (fltype)(0.0); @@ -351,11 +320,11 @@ void change_attackrate(Bitu regbase, op_type* op_pt) { } } -void change_decayrate(Bitu regbase, op_type* op_pt) { - Bits decayrate = adlibreg[ARC_ATTR_DECR+regbase]&15; +void change_decayrate(opl_context* ctx, Bitu regbase, op_type* op_pt) { + Bits decayrate = (ctx->adlibreg)[ARC_ATTR_DECR+regbase]&15; // decaymul should be 1.0 when decayrate==0 if (decayrate) { - fltype f = (fltype)(-7.4493*decrelconst[op_pt->toff&3]*recipsamp); + fltype f = (fltype)(-7.4493*decrelconst[op_pt->toff&3]*(ctx->recipsamp)); op_pt->decaymul = (fltype)(pow(FL2,f*pow(FL2,(fltype)(decayrate+(op_pt->toff>>2))))); Bits steps = (decayrate*4 + op_pt->toff) >> 2; op_pt->env_step_d = (1<<(steps<=12?12-steps:0))-1; @@ -365,11 +334,11 @@ void change_decayrate(Bitu regbase, op_type* op_pt) { } } -void change_releaserate(Bitu regbase, op_type* op_pt) { - Bits releaserate = adlibreg[ARC_SUSL_RELR+regbase]&15; +void change_releaserate(opl_context* ctx, Bitu regbase, op_type* op_pt) { + Bits releaserate = (ctx->adlibreg)[ARC_SUSL_RELR+regbase]&15; // releasemul should be 1.0 when releaserate==0 if (releaserate) { - fltype f = (fltype)(-7.4493*decrelconst[op_pt->toff&3]*recipsamp); + fltype f = (fltype)(-7.4493*decrelconst[op_pt->toff&3]*(ctx->recipsamp)); op_pt->releasemul = (fltype)(pow(FL2,f*pow(FL2,(fltype)(releaserate+(op_pt->toff>>2))))); Bits steps = (releaserate*4 + op_pt->toff) >> 2; op_pt->env_step_r = (1<<(steps<=12?12-steps:0))-1; @@ -379,8 +348,8 @@ void change_releaserate(Bitu regbase, op_type* op_pt) { } } -void change_sustainlevel(Bitu regbase, op_type* op_pt) { - Bits sustainlevel = adlibreg[ARC_SUSL_RELR+regbase]>>4; +void change_sustainlevel(opl_context* ctx, Bitu regbase, op_type* op_pt) { + Bits sustainlevel = (ctx->adlibreg)[ARC_SUSL_RELR+regbase]>>4; // sustainlevel should be 0.0 when sustainlevel==15 (max) if (sustainlevel<15) { op_pt->sustain_level = (fltype)(pow(FL2,(fltype)sustainlevel * (-FL05))); @@ -389,18 +358,16 @@ void change_sustainlevel(Bitu regbase, op_type* op_pt) { } } -void change_waveform(Bitu regbase, op_type* op_pt) { -#if defined(OPLTYPE_IS_OPL3) +void change_waveform(opl_context* ctx, Bitu regbase, op_type* op_pt) { if (regbase>=ARC_SECONDSET) regbase -= (ARC_SECONDSET-22); // second set starts at 22 -#endif // waveform selection - op_pt->cur_wmask = wavemask[wave_sel[regbase]]; - op_pt->cur_wform = &wavtable[waveform[wave_sel[regbase]]]; + op_pt->cur_wmask = wavemask[(ctx->wave_sel)[regbase]]; + op_pt->cur_wform = &(ctx->wavtable)[waveform[(ctx->wave_sel)[regbase]]]; // (might need to be adapted to waveform type here...) } -void change_keepsustain(Bitu regbase, op_type* op_pt) { - op_pt->sus_keep = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x20)>0; +void change_keepsustain(opl_context* ctx, Bitu regbase, op_type* op_pt) { + op_pt->sus_keep = ((ctx->adlibreg)[ARC_TVS_KSR_MUL+regbase]&0x20)>0; if (op_pt->op_state==OF_TYPE_SUS) { if (!op_pt->sus_keep) op_pt->op_state = OF_TYPE_SUS_NOKEEP; } else if (op_pt->op_state==OF_TYPE_SUS_NOKEEP) { @@ -409,53 +376,53 @@ void change_keepsustain(Bitu regbase, op_type* op_pt) { } // enable/disable vibrato/tremolo LFO effects -void change_vibrato(Bitu regbase, op_type* op_pt) { - op_pt->vibrato = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x40)!=0; - op_pt->tremolo = (adlibreg[ARC_TVS_KSR_MUL+regbase]&0x80)!=0; +void change_vibrato(opl_context* ctx, Bitu regbase, op_type* op_pt) { + op_pt->vibrato = ((ctx->adlibreg)[ARC_TVS_KSR_MUL+regbase]&0x40)!=0; + op_pt->tremolo = ((ctx->adlibreg)[ARC_TVS_KSR_MUL+regbase]&0x80)!=0; } // change amount of self-feedback -void change_feedback(Bitu chanbase, op_type* op_pt) { - Bits feedback = adlibreg[ARC_FEEDBACK+chanbase]&14; +void change_feedback(opl_context* ctx, Bitu chanbase, op_type* op_pt) { + Bits feedback = (ctx->adlibreg)[ARC_FEEDBACK+chanbase]&14; if (feedback) op_pt->mfbi = (Bit32s)(pow(FL2,(fltype)((feedback>>1)+8))); else op_pt->mfbi = 0; } -void change_frequency(Bitu chanbase, Bitu regbase, op_type* op_pt) { +void change_frequency(opl_context* ctx, Bitu chanbase, Bitu regbase, op_type* op_pt) { // frequency - Bit32u frn = ((((Bit32u)adlibreg[ARC_KON_BNUM+chanbase])&3)<<8) + (Bit32u)adlibreg[ARC_FREQ_NUM+chanbase]; + Bit32u frn = ((((Bit32u)(ctx->adlibreg)[ARC_KON_BNUM+chanbase])&3)<<8) + (Bit32u)(ctx->adlibreg)[ARC_FREQ_NUM+chanbase]; // block number/octave - Bit32u oct = ((((Bit32u)adlibreg[ARC_KON_BNUM+chanbase])>>2)&7); + Bit32u oct = ((((Bit32u)(ctx->adlibreg)[ARC_KON_BNUM+chanbase])>>2)&7); op_pt->freq_high = (Bit32s)((frn>>7)&7); // keysplit - Bit32u note_sel = (adlibreg[8]>>6)&1; + Bit32u note_sel = ((ctx->adlibreg)[8]>>6)&1; op_pt->toff = ((frn>>9)&(note_sel^1)) | ((frn>>8)¬e_sel); op_pt->toff += (oct<<1); // envelope scaling (KSR) - if (!(adlibreg[ARC_TVS_KSR_MUL+regbase]&0x10)) op_pt->toff >>= 2; + if (!((ctx->adlibreg)[ARC_TVS_KSR_MUL+regbase]&0x10)) op_pt->toff >>= 2; // 20+a0+b0: - op_pt->tinc = (Bit32u)((((fltype)(frn<tinc = (Bit32u)((((fltype)(frn<frqmul)[(ctx->adlibreg)[ARC_TVS_KSR_MUL+regbase]&15])); // 40+a0+b0: - fltype vol_in = (fltype)((fltype)(adlibreg[ARC_KSL_OUTLEV+regbase]&63) + - kslmul[adlibreg[ARC_KSL_OUTLEV+regbase]>>6]*kslev[oct][frn>>6]); + fltype vol_in = (fltype)((fltype)((ctx->adlibreg)[ARC_KSL_OUTLEV+regbase]&63) + + kslmul[(ctx->adlibreg)[ARC_KSL_OUTLEV+regbase]>>6]*(ctx->kslev)[oct][frn>>6]); op_pt->vol = (fltype)(pow(FL2,(fltype)(vol_in * -0.125 - 14))); // operator frequency changed, care about features that depend on it - change_attackrate(regbase,op_pt); - change_decayrate(regbase,op_pt); - change_releaserate(regbase,op_pt); + change_attackrate(ctx, regbase,op_pt); + change_decayrate(ctx, regbase,op_pt); + change_releaserate(ctx, regbase,op_pt); } -void enable_operator(Bitu regbase, op_type* op_pt, Bit32u act_type) { +void enable_operator(opl_context* ctx, Bitu regbase, op_type* op_pt, Bit32u act_type) { // check if this is really an off-on transition if (op_pt->act_state == OP_ACT_OFF) { Bits wselbase = regbase; if (wselbase>=ARC_SECONDSET) wselbase -= (ARC_SECONDSET-22); // second set starts at 22 - op_pt->tcount = wavestart[wave_sel[wselbase]]*FIXEDPT; + op_pt->tcount = wavestart[(ctx->wave_sel)[wselbase]]*FIXEDPT; // start with attack mode op_pt->op_state = OF_TYPE_ATT; @@ -463,7 +430,7 @@ void enable_operator(Bitu regbase, op_type* op_pt, Bit32u act_type) { } } -void disable_operator(op_type* op_pt, Bit32u act_type) { +void disable_operator(opl_context* ctx, op_type* op_pt, Bit32u act_type) { // check if this is really an on-off transition if (op_pt->act_state != OP_ACT_OFF) { op_pt->act_state &= (~act_type); @@ -473,68 +440,64 @@ void disable_operator(op_type* op_pt, Bit32u act_type) { } } -void adlib_init(Bit32u samplerate) { +void adlib_init(opl_context* ctx, Bit32u samplerate) { Bits i, j, oct; - int_samplerate = samplerate; + //Clear the entiere state. + memset((void *)ctx,0,sizeof(*ctx)); - generator_add = (Bit32u)(INTFREQU*FIXEDPT/int_samplerate); + (ctx->int_samplerate) = samplerate; - - memset((void *)adlibreg,0,sizeof(adlibreg)); - memset((void *)op,0,sizeof(op_type)*MAXOPERATORS); - memset((void *)wave_sel,0,sizeof(wave_sel)); + (ctx->generator_add) = (Bit32u)(INTFREQU*FIXEDPT/(ctx->int_samplerate)); for (i=0;iop)[i].op_state = OF_TYPE_OFF; + (ctx->op)[i].act_state = OP_ACT_OFF; + (ctx->op)[i].amp = 0.0; + (ctx->op)[i].step_amp = 0.0; + (ctx->op)[i].vol = 0.0; + (ctx->op)[i].tcount = 0; + (ctx->op)[i].tinc = 0; + (ctx->op)[i].toff = 0; + (ctx->op)[i].cur_wmask = wavemask[0]; + (ctx->op)[i].cur_wform = &(ctx->wavtable)[waveform[0]]; + (ctx->op)[i].freq_high = 0; + + (ctx->op)[i].generator_pos = 0; + (ctx->op)[i].cur_env_step = 0; + (ctx->op)[i].env_step_a = 0; + (ctx->op)[i].env_step_d = 0; + (ctx->op)[i].env_step_r = 0; + (ctx->op)[i].step_skip_pos_a = 0; + (ctx->op)[i].env_step_skip_a = 0; + + (ctx->op)[i].is_4op = false; + (ctx->op)[i].is_4op_attached = false; + (ctx->op)[i].left_pan = 1; + (ctx->op)[i].right_pan = 1; } - recipsamp = 1.0 / (fltype)int_samplerate; + (ctx->recipsamp) = 1.0 / (fltype)(ctx->int_samplerate); for (i=15;i>=0;i--) { - frqmul[i] = (fltype)(frqmul_tab[i]*INTFREQU/(fltype)WAVEPREC*(fltype)FIXEDPT*recipsamp); + (ctx->frqmul)[i] = (fltype)(frqmul_tab[i]*INTFREQU/(fltype)WAVEPREC*(fltype)FIXEDPT*(ctx->recipsamp)); } - status = 0; - opl_index = 0; + (ctx->status) = 0; + (ctx->opl_index) = 0; // create vibrato table - vib_table[0] = 8; - vib_table[1] = 4; - vib_table[2] = 0; - vib_table[3] = -4; - for (i=4; ivib_table)[0] = 8; + (ctx->vib_table)[1] = 4; + (ctx->vib_table)[2] = 0; + (ctx->vib_table)[3] = -4; + for (i=4; ivib_table)[i] = (ctx->vib_table)[i-4]*-1; // vibrato at ~6.1 ?? (opl3 docs say 6.1, opl4 docs say 6.0, y8950 docs say 6.4) - vibtab_add = static_cast(VIBTAB_SIZE*FIXEDPT_LFO/8192*INTFREQU/int_samplerate); - vibtab_pos = 0; + (ctx->vibtab_add) = static_cast(VIBTAB_SIZE*FIXEDPT_LFO/8192*INTFREQU/(ctx->int_samplerate)); + (ctx->vibtab_pos) = 0; - for (i=0; ivibval_const)[i] = 0; // create tremolo table @@ -548,15 +511,15 @@ void adlib_init(Bit32u samplerate) { fltype trem_val1=(fltype)(((fltype)trem_table_int[i])*4.8/26.0/6.0); // 4.8db fltype trem_val2=(fltype)((fltype)((Bit32s)(trem_table_int[i]/4))*1.2/6.0/6.0); // 1.2db (larger stepping) - trem_table[i] = (Bit32s)(pow(FL2,trem_val1)*FIXEDPT); - trem_table[TREMTAB_SIZE+i] = (Bit32s)(pow(FL2,trem_val2)*FIXEDPT); + (ctx->trem_table)[i] = (Bit32s)(pow(FL2,trem_val1)*FIXEDPT); + (ctx->trem_table)[TREMTAB_SIZE+i] = (Bit32s)(pow(FL2,trem_val2)*FIXEDPT); } // tremolo at 3.7hz - tremtab_add = (Bit32u)((fltype)TREMTAB_SIZE * TREM_FREQ * FIXEDPT_LFO / (fltype)int_samplerate); - tremtab_pos = 0; + (ctx->tremtab_add) = (Bit32u)((fltype)TREMTAB_SIZE * TREM_FREQ * FIXEDPT_LFO / (fltype)(ctx->int_samplerate)); + (ctx->tremtab_pos) = 0; - for (i=0; itremval_const)[i] = FIXEDPT; static Bitu initfirstime = 0; @@ -565,29 +528,29 @@ void adlib_init(Bit32u samplerate) { // create waveform tables for (i=0;i<(WAVEPREC>>1);i++) { - wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1) )*PI*2/WAVEPREC)); - wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1)+1)*PI*2/WAVEPREC)); - wavtable[i] = wavtable[(i<<1) +WAVEPREC]; + (ctx->wavtable)[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1) )*PI*2/WAVEPREC)); + (ctx->wavtable)[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<1)+1)*PI*2/WAVEPREC)); + (ctx->wavtable)[i] = (ctx->wavtable)[(i<<1) +WAVEPREC]; // alternative: (zero-less) /* wavtable[(i<<1) +WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<2)+1)*PI/WAVEPREC)); wavtable[(i<<1)+1+WAVEPREC] = (Bit16s)(16384*sin((fltype)((i<<2)+3)*PI/WAVEPREC)); wavtable[i] = wavtable[(i<<1)-1+WAVEPREC]; */ } for (i=0;i<(WAVEPREC>>3);i++) { - wavtable[i+(WAVEPREC<<1)] = wavtable[i+(WAVEPREC>>3)]-16384; - wavtable[i+((WAVEPREC*17)>>3)] = wavtable[i+(WAVEPREC>>2)]+16384; + (ctx->wavtable)[i+(WAVEPREC<<1)] = (ctx->wavtable)[i+(WAVEPREC>>3)]-16384; + (ctx->wavtable)[i+((WAVEPREC*17)>>3)] = (ctx->wavtable)[i+(WAVEPREC>>2)]+16384; } // key scale level table verified ([table in book]*8/3) - kslev[7][0] = 0; kslev[7][1] = 24; kslev[7][2] = 32; kslev[7][3] = 37; - kslev[7][4] = 40; kslev[7][5] = 43; kslev[7][6] = 45; kslev[7][7] = 47; - kslev[7][8] = 48; - for (i=9;i<16;i++) kslev[7][i] = (Bit8u)(i+41); + (ctx->kslev)[7][0] = 0; (ctx->kslev)[7][1] = 24; (ctx->kslev)[7][2] = 32; (ctx->kslev)[7][3] = 37; + (ctx->kslev)[7][4] = 40; (ctx->kslev)[7][5] = 43; (ctx->kslev)[7][6] = 45; (ctx->kslev)[7][7] = 47; + (ctx->kslev)[7][8] = 48; + for (i=9;i<16;i++) (ctx->kslev)[7][i] = (Bit8u)(i+41); for (j=6;j>=0;j--) { for (i=0;i<16;i++) { - oct = (Bits)kslev[j+1][i]-8; + oct = (Bits)(ctx->kslev)[j+1][i]-8; if (oct < 0) oct = 0; - kslev[j][i] = (Bit8u)oct; + (ctx->kslev)[j][i] = (Bit8u)oct; } } } @@ -596,9 +559,9 @@ void adlib_init(Bit32u samplerate) { -void adlib_write(Bitu idx, Bit8u val) { +void adlib_write(opl_context* ctx, Bitu idx, Bit8u val) { Bit32u second_set = idx&0x100; - adlibreg[idx] = val; + (ctx->adlibreg)[idx] = val; switch (idx&0xf0) { case ARC_CONTROL: @@ -611,30 +574,28 @@ void adlib_write(Bitu idx, Bit8u val) { // IRQ reset, timer mask/start if (val&0x80) { // clear IRQ bits in status register - status &= ~0x60; + (ctx->status) &= ~0x60; } else { - status = 0; + (ctx->status) = 0; } break; -#if defined(OPLTYPE_IS_OPL3) case 0x04|ARC_SECONDSET: // 4op enable/disable switches for each possible channel - op[0].is_4op = (val&1)>0; - op[3].is_4op_attached = op[0].is_4op; - op[1].is_4op = (val&2)>0; - op[4].is_4op_attached = op[1].is_4op; - op[2].is_4op = (val&4)>0; - op[5].is_4op_attached = op[2].is_4op; - op[18].is_4op = (val&8)>0; - op[21].is_4op_attached = op[18].is_4op; - op[19].is_4op = (val&16)>0; - op[22].is_4op_attached = op[19].is_4op; - op[20].is_4op = (val&32)>0; - op[23].is_4op_attached = op[20].is_4op; + (ctx->op)[0].is_4op = (val&1)>0; + (ctx->op)[3].is_4op_attached = (ctx->op)[0].is_4op; + (ctx->op)[1].is_4op = (val&2)>0; + (ctx->op)[4].is_4op_attached = (ctx->op)[1].is_4op; + (ctx->op)[2].is_4op = (val&4)>0; + (ctx->op)[5].is_4op_attached = (ctx->op)[2].is_4op; + (ctx->op)[18].is_4op = (val&8)>0; + (ctx->op)[21].is_4op_attached = (ctx->op)[18].is_4op; + (ctx->op)[19].is_4op = (val&16)>0; + (ctx->op)[22].is_4op_attached = (ctx->op)[19].is_4op; + (ctx->op)[20].is_4op = (val&32)>0; + (ctx->op)[23].is_4op_attached = (ctx->op)[20].is_4op; break; case 0x05|ARC_SECONDSET: break; -#endif case 0x08: // CSW, note select break; @@ -653,22 +614,18 @@ void adlib_write(Bitu idx, Bit8u val) { Bitu chanbase = second_set?(modop-18+ARC_SECONDSET):modop; // change tremolo/vibrato and sustain keeping of this operator - op_type* op_ptr = &op[modop+((num<3) ? 0 : 9)]; - change_keepsustain(regbase,op_ptr); - change_vibrato(regbase,op_ptr); + op_type* op_ptr = &(ctx->op)[modop+((num<3) ? 0 : 9)]; + change_keepsustain(ctx, regbase,op_ptr); + change_vibrato(ctx, regbase,op_ptr); // change frequency calculations of this operator as // key scale rate and frequency multiplicator can be changed -#if defined(OPLTYPE_IS_OPL3) - if ((adlibreg[0x105]&1) && (op[modop].is_4op_attached)) { + if (((ctx->adlibreg)[0x105]&1) && ((ctx->op)[modop].is_4op_attached)) { // operator uses frequency of channel - change_frequency(chanbase-3,regbase,op_ptr); + change_frequency(ctx, chanbase-3,regbase,op_ptr); } else { - change_frequency(chanbase,regbase,op_ptr); + change_frequency(ctx, chanbase,regbase,op_ptr); } -#else - change_frequency(chanbase,base,op_ptr); -#endif } } break; @@ -683,18 +640,14 @@ void adlib_write(Bitu idx, Bit8u val) { // change frequency calculations of this operator as // key scale level and output rate can be changed - op_type* op_ptr = &op[modop+((num<3) ? 0 : 9)]; -#if defined(OPLTYPE_IS_OPL3) + op_type* op_ptr = &(ctx->op)[modop+((num<3) ? 0 : 9)]; Bitu regbase = base+second_set; - if ((adlibreg[0x105]&1) && (op[modop].is_4op_attached)) { + if (((ctx->adlibreg)[0x105]&1) && ((ctx->op)[modop].is_4op_attached)) { // operator uses frequency of channel - change_frequency(chanbase-3,regbase,op_ptr); + change_frequency(ctx, chanbase-3,regbase,op_ptr); } else { - change_frequency(chanbase,regbase,op_ptr); + change_frequency(ctx, chanbase,regbase,op_ptr); } -#else - change_frequency(chanbase,base,op_ptr); -#endif } } break; @@ -707,9 +660,9 @@ void adlib_write(Bitu idx, Bit8u val) { Bitu regbase = base+second_set; // change attack rate and decay rate of this operator - op_type* op_ptr = &op[regbase2op[second_set?(base+22):base]]; - change_attackrate(regbase,op_ptr); - change_decayrate(regbase,op_ptr); + op_type* op_ptr = &(ctx->op)[regbase2op[second_set?(base+22):base]]; + change_attackrate(ctx, regbase,op_ptr); + change_decayrate(ctx, regbase,op_ptr); } } break; @@ -722,9 +675,9 @@ void adlib_write(Bitu idx, Bit8u val) { Bitu regbase = base+second_set; // change sustain level and release rate of this operator - op_type* op_ptr = &op[regbase2op[second_set?(base+22):base]]; - change_releaserate(regbase,op_ptr); - change_sustainlevel(regbase,op_ptr); + op_type* op_ptr = &(ctx->op)[regbase2op[second_set?(base+22):base]]; + change_releaserate(ctx, regbase,op_ptr); + change_sustainlevel(ctx, regbase,op_ptr); } } break; @@ -733,64 +686,58 @@ void adlib_write(Bitu idx, Bit8u val) { Bitu base = (idx-ARC_FREQ_NUM)&0xff; if (base<9) { Bits opbase = second_set?(base+18):base; -#if defined(OPLTYPE_IS_OPL3) - if ((adlibreg[0x105]&1) && op[opbase].is_4op_attached) break; -#endif + if (((ctx->adlibreg)[0x105]&1) && (ctx->op)[opbase].is_4op_attached) break; // regbase of modulator: Bits modbase = modulatorbase[base]+second_set; Bitu chanbase = base+second_set; - change_frequency(chanbase,modbase,&op[opbase]); - change_frequency(chanbase,modbase+3,&op[opbase+9]); -#if defined(OPLTYPE_IS_OPL3) + change_frequency(ctx, chanbase,modbase,&(ctx->op)[opbase]); + change_frequency(ctx, chanbase,modbase+3,&(ctx->op)[opbase+9]); // for 4op channels all four operators are modified to the frequency of the channel - if ((adlibreg[0x105]&1) && op[second_set?(base+18):base].is_4op) { - change_frequency(chanbase,modbase+8,&op[opbase+3]); - change_frequency(chanbase,modbase+3+8,&op[opbase+3+9]); + if (((ctx->adlibreg)[0x105]&1) && (ctx->op)[second_set?(base+18):base].is_4op) { + change_frequency(ctx, chanbase,modbase+8,&(ctx->op)[opbase+3]); + change_frequency(ctx, chanbase,modbase+3+8,&(ctx->op)[opbase+3+9]); } -#endif } } break; case ARC_KON_BNUM: { if (idx == ARC_PERC_MODE) { -#if defined(OPLTYPE_IS_OPL3) if (second_set) return; -#endif if ((val&0x30) == 0x30) { // BassDrum active - enable_operator(16,&op[6],OP_ACT_PERC); - change_frequency(6,16,&op[6]); - enable_operator(16+3,&op[6+9],OP_ACT_PERC); - change_frequency(6,16+3,&op[6+9]); + enable_operator(ctx, 16,&(ctx->op)[6],OP_ACT_PERC); + change_frequency(ctx, 6,16,&(ctx->op)[6]); + enable_operator(ctx, 16+3,&(ctx->op)[6+9],OP_ACT_PERC); + change_frequency(ctx, 6,16+3,&(ctx->op)[6+9]); } else { - disable_operator(&op[6],OP_ACT_PERC); - disable_operator(&op[6+9],OP_ACT_PERC); + disable_operator(ctx, &(ctx->op)[6],OP_ACT_PERC); + disable_operator(ctx, &(ctx->op)[6+9],OP_ACT_PERC); } if ((val&0x28) == 0x28) { // Snare active - enable_operator(17+3,&op[16],OP_ACT_PERC); - change_frequency(7,17+3,&op[16]); + enable_operator(ctx, 17+3,&(ctx->op)[16],OP_ACT_PERC); + change_frequency(ctx, 7,17+3,&(ctx->op)[16]); } else { - disable_operator(&op[16],OP_ACT_PERC); + disable_operator(ctx, &(ctx->op)[16],OP_ACT_PERC); } if ((val&0x24) == 0x24) { // TomTom active - enable_operator(18,&op[8],OP_ACT_PERC); - change_frequency(8,18,&op[8]); + enable_operator(ctx, 18,&(ctx->op)[8],OP_ACT_PERC); + change_frequency(ctx, 8,18,&(ctx->op)[8]); } else { - disable_operator(&op[8],OP_ACT_PERC); + disable_operator(ctx, &(ctx->op)[8],OP_ACT_PERC); } if ((val&0x22) == 0x22) { // Cymbal active - enable_operator(18+3,&op[8+9],OP_ACT_PERC); - change_frequency(8,18+3,&op[8+9]); + enable_operator(ctx, 18+3,&(ctx->op)[8+9],OP_ACT_PERC); + change_frequency(ctx, 8,18+3,&(ctx->op)[8+9]); } else { - disable_operator(&op[8+9],OP_ACT_PERC); + disable_operator(ctx, &(ctx->op)[8+9],OP_ACT_PERC); } if ((val&0x21) == 0x21) { // Hihat active - enable_operator(17,&op[7],OP_ACT_PERC); - change_frequency(7,17,&op[7]); + enable_operator(ctx, 17,&(ctx->op)[7],OP_ACT_PERC); + change_frequency(ctx, 7,17,&(ctx->op)[7]); } else { - disable_operator(&op[7],OP_ACT_PERC); + disable_operator(ctx, &(ctx->op)[7],OP_ACT_PERC); } break; @@ -799,52 +746,44 @@ void adlib_write(Bitu idx, Bit8u val) { Bitu base = (idx-ARC_KON_BNUM)&0xff; if (base<9) { Bits opbase = second_set?(base+18):base; -#if defined(OPLTYPE_IS_OPL3) - if ((adlibreg[0x105]&1) && op[opbase].is_4op_attached) break; -#endif + if (((ctx->adlibreg)[0x105]&1) && (ctx->op)[opbase].is_4op_attached) break; // regbase of modulator: Bits modbase = modulatorbase[base]+second_set; if (val&32) { // operator switched on - enable_operator(modbase,&op[opbase],OP_ACT_NORMAL); // modulator (if 2op) - enable_operator(modbase+3,&op[opbase+9],OP_ACT_NORMAL); // carrier (if 2op) -#if defined(OPLTYPE_IS_OPL3) + enable_operator(ctx, modbase,&(ctx->op)[opbase],OP_ACT_NORMAL); // modulator (if 2op) + enable_operator(ctx, modbase+3,&(ctx->op)[opbase+9],OP_ACT_NORMAL); // carrier (if 2op) // for 4op channels all four operators are switched on - if ((adlibreg[0x105]&1) && op[opbase].is_4op) { + if (((ctx->adlibreg)[0x105]&1) && (ctx->op)[opbase].is_4op) { // turn on chan+3 operators as well - enable_operator(modbase+8,&op[opbase+3],OP_ACT_NORMAL); - enable_operator(modbase+3+8,&op[opbase+3+9],OP_ACT_NORMAL); + enable_operator(ctx, modbase+8,&(ctx->op)[opbase+3],OP_ACT_NORMAL); + enable_operator(ctx, modbase+3+8,&(ctx->op)[opbase+3+9],OP_ACT_NORMAL); } -#endif } else { // operator switched off - disable_operator(&op[opbase],OP_ACT_NORMAL); - disable_operator(&op[opbase+9],OP_ACT_NORMAL); -#if defined(OPLTYPE_IS_OPL3) + disable_operator(ctx, &(ctx->op)[opbase],OP_ACT_NORMAL); + disable_operator(ctx, &(ctx->op)[opbase+9],OP_ACT_NORMAL); // for 4op channels all four operators are switched off - if ((adlibreg[0x105]&1) && op[opbase].is_4op) { + if (((ctx->adlibreg)[0x105]&1) && (ctx->op)[opbase].is_4op) { // turn off chan+3 operators as well - disable_operator(&op[opbase+3],OP_ACT_NORMAL); - disable_operator(&op[opbase+3+9],OP_ACT_NORMAL); + disable_operator(ctx, &(ctx->op)[opbase+3],OP_ACT_NORMAL); + disable_operator(ctx, &(ctx->op)[opbase+3+9],OP_ACT_NORMAL); } -#endif } Bitu chanbase = base+second_set; // change frequency calculations of modulator and carrier (2op) as // the frequency of the channel has changed - change_frequency(chanbase,modbase,&op[opbase]); - change_frequency(chanbase,modbase+3,&op[opbase+9]); -#if defined(OPLTYPE_IS_OPL3) + change_frequency(ctx, chanbase,modbase,&(ctx->op)[opbase]); + change_frequency(ctx, chanbase,modbase+3,&(ctx->op)[opbase+9]); // for 4op channels all four operators are modified to the frequency of the channel - if ((adlibreg[0x105]&1) && op[second_set?(base+18):base].is_4op) { + if (((ctx->adlibreg)[0x105]&1) && (ctx->op)[second_set?(base+18):base].is_4op) { // change frequency calculations of chan+3 operators as well - change_frequency(chanbase,modbase+8,&op[opbase+3]); - change_frequency(chanbase,modbase+3+8,&op[opbase+3+9]); + change_frequency(ctx, chanbase,modbase+8,&(ctx->op)[opbase+3]); + change_frequency(ctx, chanbase,modbase+3+8,&(ctx->op)[opbase+3+9]); } -#endif } } break; @@ -854,12 +793,10 @@ void adlib_write(Bitu idx, Bit8u val) { if (base<9) { Bits opbase = second_set?(base+18):base; Bitu chanbase = base+second_set; - change_feedback(chanbase,&op[opbase]); -#if defined(OPLTYPE_IS_OPL3) + change_feedback(ctx, chanbase,&(ctx->op)[opbase]); // OPL3 panning - op[opbase].left_pan = ((val&0x10)>>4); - op[opbase].right_pan = ((val&0x20)>>5); -#endif + (ctx->op)[opbase].left_pan = ((val&0x10)>>4); + (ctx->op)[opbase].right_pan = ((val&0x20)>>5); } } break; @@ -868,21 +805,12 @@ void adlib_write(Bitu idx, Bit8u val) { int num = idx&7; Bitu base = (idx-ARC_WAVE_SEL)&0xff; if ((num<6) && (base<22)) { -#if defined(OPLTYPE_IS_OPL3) - Bits wselbase = second_set?(base+22):base; // for easier mapping onto wave_sel[] + Bits wselbase = second_set?(base+22):base; // for easier mapping onto (ctx->wave_sel)[] // change waveform - if (adlibreg[0x105]&1) wave_sel[wselbase] = val&7; // opl3 mode enabled, all waveforms accessible - else wave_sel[wselbase] = val&3; - op_type* op_ptr = &op[regbase2modop[wselbase]+((num<3) ? 0 : 9)]; - change_waveform(wselbase,op_ptr); -#else - if (adlibreg[0x01]&0x20) { - // wave selection enabled, change waveform - wave_sel[base] = val&3; - op_type* op_ptr = &op[regbase2modop[base]+((num<3) ? 0 : 9)]; - change_waveform(base,op_ptr); - } -#endif + if ((ctx->adlibreg)[0x105]&1) (ctx->wave_sel)[wselbase] = val&7; // opl3 mode enabled, all waveforms accessible + else (ctx->wave_sel)[wselbase] = val&3; + op_type* op_ptr = &(ctx->op)[regbase2modop[wselbase]+((num<3) ? 0 : 9)]; + change_waveform(ctx, wselbase,op_ptr); } } break; @@ -892,30 +820,20 @@ void adlib_write(Bitu idx, Bit8u val) { } -Bitu adlib_reg_read(Bitu port) { -#if defined(OPLTYPE_IS_OPL3) +Bitu adlib_reg_read(opl_context* ctx, Bitu port) { // opl3-detection routines require ret&6 to be zero if ((port&1)==0) { - return status; + return (ctx->status); } return 0x00; -#else - // opl2-detection routines require ret&6 to be 6 - if ((port&1)==0) { - return status|6; - } - return 0xff; -#endif } -void adlib_write_index(Bitu port, Bit8u val) { - opl_index = val; -#if defined(OPLTYPE_IS_OPL3) +void adlib_write_index(opl_context* ctx, Bitu port, Bit8u val) { + (ctx->opl_index) = val; if ((port&3)!=0) { // possibly second set - if (((adlibreg[0x105]&1)!=0) || (opl_index==5)) opl_index |= ARC_SECONDSET; + if ((((ctx->adlibreg)[0x105]&1)!=0) || ((ctx->opl_index)==5)) (ctx->opl_index) |= ARC_SECONDSET; } -#endif } static void OPL_INLINE clipit16(Bit32s ival, Bit16s* outval) { @@ -936,28 +854,21 @@ static void OPL_INLINE clipit16(Bit32s ival, Bit16s* outval) { // uses cptr and chanval, outputs into outbufl(/outbufr) // for opl3 check if opl3-mode is enabled (which uses stereo panning) #undef CHANVAL_OUT -#if defined(OPLTYPE_IS_OPL3) #define CHANVAL_OUT \ - if (adlibreg[0x105]&1) { \ + if ((ctx->adlibreg)[0x105]&1) { \ outbufl[i] += chanval*cptr[0].left_pan; \ outbufr[i] += chanval*cptr[0].right_pan; \ } else { \ outbufl[i] += chanval; \ } -#else -#define CHANVAL_OUT \ - outbufl[i] += chanval; -#endif -void adlib_getsample(Bit16s* sndptr, Bits numsamples) { +void adlib_getsample(opl_context* ctx, Bit16s* sndptr, Bits numsamples) { Bits i, endsamples; op_type* cptr; Bit32s outbufl[BLOCKBUF_SIZE]; -#if defined(OPLTYPE_IS_OPL3) // second output buffer (right channel for opl3 stereo) Bit32s outbufr[BLOCKBUF_SIZE]; -#endif // vibrato/tremolo lookup tables (global, to possibly be used by all operators) Bit32s vib_lut[BLOCKBUF_SIZE]; @@ -970,45 +881,43 @@ void adlib_getsample(Bit16s* sndptr, Bits numsamples) { if (endsamples>BLOCKBUF_SIZE) endsamples = BLOCKBUF_SIZE; memset((void*)&outbufl,0,endsamples*sizeof(Bit32s)); -#if defined(OPLTYPE_IS_OPL3) // clear second output buffer (opl3 stereo) - if (adlibreg[0x105]&1) memset((void*)&outbufr,0,endsamples*sizeof(Bit32s)); -#endif + if ((ctx->adlibreg)[0x105]&1) memset((void*)&outbufr,0,endsamples*sizeof(Bit32s)); // calculate vibrato/tremolo lookup tables - Bit32s vib_tshift = ((adlibreg[ARC_PERC_MODE]&0x40)==0) ? 1 : 0; // 14cents/7cents switching + Bit32s vib_tshift = (((ctx->adlibreg)[ARC_PERC_MODE]&0x40)==0) ? 1 : 0; // 14cents/7cents switching for (i=0;i=VIBTAB_SIZE) vibtab_pos-=VIBTAB_SIZE*FIXEDPT_LFO; - vib_lut[i] = vib_table[vibtab_pos/FIXEDPT_LFO]>>vib_tshift; // 14cents (14/100 of a semitone) or 7cents + (ctx->vibtab_pos) += (ctx->vibtab_add); + if ((ctx->vibtab_pos)/FIXEDPT_LFO>=VIBTAB_SIZE) (ctx->vibtab_pos)-=VIBTAB_SIZE*FIXEDPT_LFO; + vib_lut[i] = (ctx->vib_table)[(ctx->vibtab_pos)/FIXEDPT_LFO]>>vib_tshift; // 14cents (14/100 of a semitone) or 7cents // cycle through tremolo table - tremtab_pos += tremtab_add; - if (tremtab_pos/FIXEDPT_LFO>=TREMTAB_SIZE) tremtab_pos-=TREMTAB_SIZE*FIXEDPT_LFO; - if (adlibreg[ARC_PERC_MODE]&0x80) trem_lut[i] = trem_table[tremtab_pos/FIXEDPT_LFO]; - else trem_lut[i] = trem_table[TREMTAB_SIZE+tremtab_pos/FIXEDPT_LFO]; + (ctx->tremtab_pos) += (ctx->tremtab_add); + if ((ctx->tremtab_pos)/FIXEDPT_LFO>=TREMTAB_SIZE) (ctx->tremtab_pos)-=TREMTAB_SIZE*FIXEDPT_LFO; + if ((ctx->adlibreg)[ARC_PERC_MODE]&0x80) trem_lut[i] = (ctx->trem_table)[(ctx->tremtab_pos)/FIXEDPT_LFO]; + else trem_lut[i] = (ctx->trem_table)[TREMTAB_SIZE+(ctx->tremtab_pos)/FIXEDPT_LFO]; } - if (adlibreg[ARC_PERC_MODE]&0x20) { + if ((ctx->adlibreg)[ARC_PERC_MODE]&0x20) { //BassDrum - cptr = &op[6]; - if (adlibreg[ARC_FEEDBACK+6]&1) { + cptr = &(ctx->op)[6]; + if ((ctx->adlibreg)[ARC_FEEDBACK+6]&1) { // additive synthesis if (cptr[9].op_state != OF_TYPE_OFF) { if (cptr[9].vibrato) { - vibval1 = vibval_var1; + (ctx->vibval1) = (ctx->vibval_var1); for (i=0;ivibval1)[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval1) = (ctx->vibval_const); + if (cptr[9].tremolo) (ctx->tremval1) = trem_lut; // tremolo enabled, use table + else (ctx->tremval1) = (ctx->tremval_const); // calculate channel output for (i=0;ivibval1)[i]); + opfuncs[cptr[9].op_state](ctx, &cptr[9]); + operator_output(ctx, &cptr[9],0,(ctx->tremval1)[i]); Bit32s chanval = cptr[9].cval*2; CHANVAL_OUT @@ -1018,29 +927,29 @@ void adlib_getsample(Bit16s* sndptr, Bits numsamples) { // frequency modulation if ((cptr[9].op_state != OF_TYPE_OFF) || (cptr[0].op_state != OF_TYPE_OFF)) { if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { - vibval1 = vibval_var1; + (ctx->vibval1) = (ctx->vibval_var1); for (i=0;ivibval1)[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval1) = (ctx->vibval_const); if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { - vibval2 = vibval_var2; + (ctx->vibval2) = (ctx->vibval_var2); for (i=0;ivibval2)[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval2) = (ctx->vibval_const); + if (cptr[0].tremolo) (ctx->tremval1) = trem_lut; // tremolo enabled, use table + else (ctx->tremval1) = (ctx->tremval_const); + if (cptr[9].tremolo) (ctx->tremval2) = trem_lut; // tremolo enabled, use table + else (ctx->tremval2) = (ctx->tremval_const); // calculate channel output for (i=0;ivibval1)[i]); + opfuncs[cptr[0].op_state](ctx, &cptr[0]); + operator_output(ctx, &cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,(ctx->tremval1)[i]); - operator_advance(&cptr[9],vibval2[i]); - opfuncs[cptr[9].op_state](&cptr[9]); - operator_output(&cptr[9],cptr[0].cval*FIXEDPT,tremval2[i]); + operator_advance(ctx, &cptr[9],(ctx->vibval2)[i]); + opfuncs[cptr[9].op_state](ctx, &cptr[9]); + operator_output(ctx, &cptr[9],cptr[0].cval*FIXEDPT,(ctx->tremval2)[i]); Bit32s chanval = cptr[9].cval*2; CHANVAL_OUT @@ -1049,118 +958,111 @@ void adlib_getsample(Bit16s* sndptr, Bits numsamples) { } //TomTom (j=8) - if (op[8].op_state != OF_TYPE_OFF) { - cptr = &op[8]; + if ((ctx->op)[8].op_state != OF_TYPE_OFF) { + cptr = &(ctx->op)[8]; if (cptr[0].vibrato) { - vibval3 = vibval_var1; + (ctx->vibval3) = (ctx->vibval_var1); for (i=0;ivibval3)[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval3) = (ctx->vibval_const); - if (cptr[0].tremolo) tremval3 = trem_lut; // tremolo enabled, use table - else tremval3 = tremval_const; + if (cptr[0].tremolo) (ctx->tremval3) = trem_lut; // tremolo enabled, use table + else (ctx->tremval3) = (ctx->tremval_const); // calculate channel output for (i=0;ivibval3)[i]); + opfuncs[cptr[0].op_state](ctx, &cptr[0]); //TomTom + operator_output(ctx, &cptr[0],0,(ctx->tremval3)[i]); Bit32s chanval = cptr[0].cval*2; CHANVAL_OUT } } //Snare/Hihat (j=7), Cymbal (j=8) - if ((op[7].op_state != OF_TYPE_OFF) || (op[16].op_state != OF_TYPE_OFF) || - (op[17].op_state != OF_TYPE_OFF)) { - cptr = &op[7]; + if (((ctx->op)[7].op_state != OF_TYPE_OFF) || ((ctx->op)[16].op_state != OF_TYPE_OFF) || + ((ctx->op)[17].op_state != OF_TYPE_OFF)) { + cptr = &(ctx->op)[7]; if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { - vibval1 = vibval_var1; + (ctx->vibval1) = (ctx->vibval_var1); for (i=0;ivibval1)[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval1) = (ctx->vibval_const); if ((cptr[9].vibrato) && (cptr[9].op_state == OF_TYPE_OFF)) { - vibval2 = vibval_var2; + (ctx->vibval2) = (ctx->vibval_var2); for (i=0;ivibval2)[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval2) = (ctx->vibval_const); - if (cptr[0].tremolo) tremval1 = trem_lut; // tremolo enabled, use table - else tremval1 = tremval_const; - if (cptr[9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table - else tremval2 = tremval_const; + if (cptr[0].tremolo) (ctx->tremval1) = trem_lut; // tremolo enabled, use table + else (ctx->tremval1) = (ctx->tremval_const); + if (cptr[9].tremolo) (ctx->tremval2) = trem_lut; // tremolo enabled, use table + else (ctx->tremval2) = (ctx->tremval_const); - cptr = &op[8]; + cptr = &(ctx->op)[8]; if ((cptr[9].vibrato) && (cptr[9].op_state == OF_TYPE_OFF)) { - vibval4 = vibval_var2; + (ctx->vibval4) = (ctx->vibval_var2); for (i=0;ivibval4)[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval4) = (ctx->vibval_const); - if (cptr[9].tremolo) tremval4 = trem_lut; // tremolo enabled, use table - else tremval4 = tremval_const; + if (cptr[9].tremolo) (ctx->tremval4) = trem_lut; // tremolo enabled, use table + else (ctx->tremval4) = (ctx->tremval_const); // calculate channel output for (i=0;iop)[7],(ctx->vibval1)[i],&(ctx->op)[7+9],(ctx->vibval2)[i],&(ctx->op)[8+9],(ctx->vibval4)[i]); - opfuncs[op[7].op_state](&op[7]); //Hihat - operator_output(&op[7],0,tremval1[i]); + opfuncs[(ctx->op)[7].op_state](ctx, &(ctx->op)[7]); //Hihat + operator_output(ctx, &(ctx->op)[7],0,(ctx->tremval1)[i]); - opfuncs[op[7+9].op_state](&op[7+9]); //Snare - operator_output(&op[7+9],0,tremval2[i]); + opfuncs[(ctx->op)[7+9].op_state](ctx, &(ctx->op)[7+9]); //Snare + operator_output(ctx, &(ctx->op)[7+9],0,(ctx->tremval2)[i]); - opfuncs[op[8+9].op_state](&op[8+9]); //Cymbal - operator_output(&op[8+9],0,tremval4[i]); + opfuncs[(ctx->op)[8+9].op_state](ctx, &(ctx->op)[8+9]); //Cymbal + operator_output(ctx, &(ctx->op)[8+9],0,(ctx->tremval4)[i]); - Bit32s chanval = (op[7].cval + op[7+9].cval + op[8+9].cval)*2; + Bit32s chanval = ((ctx->op)[7].cval + (ctx->op)[7+9].cval + (ctx->op)[8+9].cval)*2; CHANVAL_OUT } } } Bitu max_channel = NUM_CHANNELS; -#if defined(OPLTYPE_IS_OPL3) - if ((adlibreg[0x105]&1)==0) max_channel = NUM_CHANNELS/2; -#endif + if (((ctx->adlibreg)[0x105]&1)==0) max_channel = NUM_CHANNELS/2; for (Bits cur_ch=max_channel-1; cur_ch>=0; cur_ch--) { // skip drum/percussion operators - if ((adlibreg[ARC_PERC_MODE]&0x20) && (cur_ch >= 6) && (cur_ch < 9)) continue; + if (((ctx->adlibreg)[ARC_PERC_MODE]&0x20) && (cur_ch >= 6) && (cur_ch < 9)) continue; Bitu k = cur_ch; -#if defined(OPLTYPE_IS_OPL3) if (cur_ch < 9) { - cptr = &op[cur_ch]; + cptr = &(ctx->op)[cur_ch]; } else { - cptr = &op[cur_ch+9]; // second set is operator18-operator35 + cptr = &(ctx->op)[cur_ch+9]; // second set is operator18-operator35 k += (-9+256); // second set uses registers 0x100 onwards } // check if this operator is part of a 4-op - if ((adlibreg[0x105]&1) && cptr->is_4op_attached) continue; -#else - cptr = &op[cur_ch]; -#endif + if (((ctx->adlibreg)[0x105]&1) && cptr->is_4op_attached) continue; // check for FM/AM - if (adlibreg[ARC_FEEDBACK+k]&1) { -#if defined(OPLTYPE_IS_OPL3) - if ((adlibreg[0x105]&1) && cptr->is_4op) { - if (adlibreg[ARC_FEEDBACK+k+3]&1) { + if ((ctx->adlibreg)[ARC_FEEDBACK+k]&1) { + if (((ctx->adlibreg)[0x105]&1) && cptr->is_4op) { + if ((ctx->adlibreg)[ARC_FEEDBACK+k+3]&1) { // AM-AM-style synthesis (op1[fb] + (op2 * op3) + op4) if (cptr[0].op_state != OF_TYPE_OFF) { if (cptr[0].vibrato) { - vibval1 = vibval_var1; + (ctx->vibval1) = (ctx->vibval_var1); for (i=0;ivibval1)[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval1) = (ctx->vibval_const); + if (cptr[0].tremolo) (ctx->tremval1) = trem_lut; // tremolo enabled, use table + else (ctx->tremval1) = (ctx->tremval_const); // calculate channel output for (i=0;ivibval1)[i]); + opfuncs[cptr[0].op_state](ctx, &cptr[0]); + operator_output(ctx, &cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,(ctx->tremval1)[i]); Bit32s chanval = cptr[0].cval; CHANVAL_OUT @@ -1169,24 +1071,24 @@ void adlib_getsample(Bit16s* sndptr, Bits numsamples) { if ((cptr[3].op_state != OF_TYPE_OFF) || (cptr[9].op_state != OF_TYPE_OFF)) { if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { - vibval1 = vibval_var1; + (ctx->vibval1) = (ctx->vibval_var1); for (i=0;ivibval1)[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval1) = (ctx->vibval_const); + if (cptr[9].tremolo) (ctx->tremval1) = trem_lut; // tremolo enabled, use table + else (ctx->tremval1) = (ctx->tremval_const); + if (cptr[3].tremolo) (ctx->tremval2) = trem_lut; // tremolo enabled, use table + else (ctx->tremval2) = (ctx->tremval_const); // calculate channel output for (i=0;ivibval1)[i]); + opfuncs[cptr[9].op_state](ctx, &cptr[9]); + operator_output(ctx, &cptr[9],0,(ctx->tremval1)[i]); - operator_advance(&cptr[3],0); - opfuncs[cptr[3].op_state](&cptr[3]); - operator_output(&cptr[3],cptr[9].cval*FIXEDPT,tremval2[i]); + operator_advance(ctx, &cptr[3],0); + opfuncs[cptr[3].op_state](ctx, &cptr[3]); + operator_output(ctx, &cptr[3],cptr[9].cval*FIXEDPT,(ctx->tremval2)[i]); Bit32s chanval = cptr[3].cval; CHANVAL_OUT @@ -1194,14 +1096,14 @@ void adlib_getsample(Bit16s* sndptr, Bits numsamples) { } if (cptr[3+9].op_state != OF_TYPE_OFF) { - if (cptr[3+9].tremolo) tremval1 = trem_lut; // tremolo enabled, use table - else tremval1 = tremval_const; + if (cptr[3+9].tremolo) (ctx->tremval1) = trem_lut; // tremolo enabled, use table + else (ctx->tremval1) = (ctx->tremval_const); // calculate channel output for (i=0;itremval1)[i]); Bit32s chanval = cptr[3+9].cval; CHANVAL_OUT @@ -1211,18 +1113,18 @@ void adlib_getsample(Bit16s* sndptr, Bits numsamples) { // AM-FM-style synthesis (op1[fb] + (op2 * op3 * op4)) if (cptr[0].op_state != OF_TYPE_OFF) { if (cptr[0].vibrato) { - vibval1 = vibval_var1; + (ctx->vibval1) = (ctx->vibval_var1); for (i=0;ivibval1)[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval1) = (ctx->vibval_const); + if (cptr[0].tremolo) (ctx->tremval1) = trem_lut; // tremolo enabled, use table + else (ctx->tremval1) = (ctx->tremval_const); // calculate channel output for (i=0;ivibval1)[i]); + opfuncs[cptr[0].op_state](ctx, &cptr[0]); + operator_output(ctx, &cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,(ctx->tremval1)[i]); Bit32s chanval = cptr[0].cval; CHANVAL_OUT @@ -1231,30 +1133,30 @@ void adlib_getsample(Bit16s* sndptr, Bits numsamples) { if ((cptr[9].op_state != OF_TYPE_OFF) || (cptr[3].op_state != OF_TYPE_OFF) || (cptr[3+9].op_state != OF_TYPE_OFF)) { if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { - vibval1 = vibval_var1; + (ctx->vibval1) = (ctx->vibval_var1); for (i=0;ivibval1)[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval1) = (ctx->vibval_const); + if (cptr[9].tremolo) (ctx->tremval1) = trem_lut; // tremolo enabled, use table + else (ctx->tremval1) = (ctx->tremval_const); + if (cptr[3].tremolo) (ctx->tremval2) = trem_lut; // tremolo enabled, use table + else (ctx->tremval2) = (ctx->tremval_const); + if (cptr[3+9].tremolo) (ctx->tremval3) = trem_lut; // tremolo enabled, use table + else (ctx->tremval3) = (ctx->tremval_const); // calculate channel output for (i=0;ivibval1)[i]); + opfuncs[cptr[9].op_state](ctx, &cptr[9]); + operator_output(ctx, &cptr[9],0,(ctx->tremval1)[i]); - operator_advance(&cptr[3],0); - opfuncs[cptr[3].op_state](&cptr[3]); - operator_output(&cptr[3],cptr[9].cval*FIXEDPT,tremval2[i]); + operator_advance(ctx, &cptr[3],0); + opfuncs[cptr[3].op_state](ctx, &cptr[3]); + operator_output(ctx, &cptr[3],cptr[9].cval*FIXEDPT,(ctx->tremval2)[i]); - operator_advance(&cptr[3+9],0); - opfuncs[cptr[3+9].op_state](&cptr[3+9]); - operator_output(&cptr[3+9],cptr[3].cval*FIXEDPT,tremval3[i]); + operator_advance(ctx, &cptr[3+9],0); + opfuncs[cptr[3+9].op_state](ctx, &cptr[3+9]); + operator_output(ctx, &cptr[3+9],cptr[3].cval*FIXEDPT,(ctx->tremval3)[i]); Bit32s chanval = cptr[3+9].cval; CHANVAL_OUT @@ -1263,69 +1165,67 @@ void adlib_getsample(Bit16s* sndptr, Bits numsamples) { } continue; } -#endif // 2op additive synthesis if ((cptr[9].op_state == OF_TYPE_OFF) && (cptr[0].op_state == OF_TYPE_OFF)) continue; if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { - vibval1 = vibval_var1; + (ctx->vibval1) = (ctx->vibval_var1); for (i=0;ivibval1)[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval1) = (ctx->vibval_const); if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { - vibval2 = vibval_var2; + (ctx->vibval2) = (ctx->vibval_var2); for (i=0;ivibval2)[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval2) = (ctx->vibval_const); + if (cptr[0].tremolo) (ctx->tremval1) = trem_lut; // tremolo enabled, use table + else (ctx->tremval1) = (ctx->tremval_const); + if (cptr[9].tremolo) (ctx->tremval2) = trem_lut; // tremolo enabled, use table + else (ctx->tremval2) = (ctx->tremval_const); // calculate channel output for (i=0;ivibval1)[i]); + opfuncs[cptr[0].op_state](ctx, &cptr[0]); + operator_output(ctx, &cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,(ctx->tremval1)[i]); // carrier2 - operator_advance(&cptr[9],vibval2[i]); - opfuncs[cptr[9].op_state](&cptr[9]); - operator_output(&cptr[9],0,tremval2[i]); + operator_advance(ctx, &cptr[9],(ctx->vibval2)[i]); + opfuncs[cptr[9].op_state](ctx, &cptr[9]); + operator_output(ctx, &cptr[9],0,(ctx->tremval2)[i]); Bit32s chanval = cptr[9].cval + cptr[0].cval; CHANVAL_OUT } } else { -#if defined(OPLTYPE_IS_OPL3) - if ((adlibreg[0x105]&1) && cptr->is_4op) { - if (adlibreg[ARC_FEEDBACK+k+3]&1) { + if (((ctx->adlibreg)[0x105]&1) && cptr->is_4op) { + if ((ctx->adlibreg)[ARC_FEEDBACK+k+3]&1) { // FM-AM-style synthesis ((op1[fb] * op2) + (op3 * op4)) if ((cptr[0].op_state != OF_TYPE_OFF) || (cptr[9].op_state != OF_TYPE_OFF)) { if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { - vibval1 = vibval_var1; + (ctx->vibval1) = (ctx->vibval_var1); for (i=0;ivibval1)[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval1) = (ctx->vibval_const); if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { - vibval2 = vibval_var2; + (ctx->vibval2) = (ctx->vibval_var2); for (i=0;ivibval2)[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval2) = (ctx->vibval_const); + if (cptr[0].tremolo) (ctx->tremval1) = trem_lut; // tremolo enabled, use table + else (ctx->tremval1) = (ctx->tremval_const); + if (cptr[9].tremolo) (ctx->tremval2) = trem_lut; // tremolo enabled, use table + else (ctx->tremval2) = (ctx->tremval_const); // calculate channel output for (i=0;ivibval1)[i]); + opfuncs[cptr[0].op_state](ctx, &cptr[0]); + operator_output(ctx, &cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,(ctx->tremval1)[i]); - operator_advance(&cptr[9],vibval2[i]); - opfuncs[cptr[9].op_state](&cptr[9]); - operator_output(&cptr[9],cptr[0].cval*FIXEDPT,tremval2[i]); + operator_advance(ctx, &cptr[9],(ctx->vibval2)[i]); + opfuncs[cptr[9].op_state](ctx, &cptr[9]); + operator_output(ctx, &cptr[9],cptr[0].cval*FIXEDPT,(ctx->tremval2)[i]); Bit32s chanval = cptr[9].cval; CHANVAL_OUT @@ -1333,20 +1233,20 @@ void adlib_getsample(Bit16s* sndptr, Bits numsamples) { } if ((cptr[3].op_state != OF_TYPE_OFF) || (cptr[3+9].op_state != OF_TYPE_OFF)) { - if (cptr[3].tremolo) tremval1 = trem_lut; // tremolo enabled, use table - else tremval1 = tremval_const; - if (cptr[3+9].tremolo) tremval2 = trem_lut; // tremolo enabled, use table - else tremval2 = tremval_const; + if (cptr[3].tremolo) (ctx->tremval1) = trem_lut; // tremolo enabled, use table + else (ctx->tremval1) = (ctx->tremval_const); + if (cptr[3+9].tremolo) (ctx->tremval2) = trem_lut; // tremolo enabled, use table + else (ctx->tremval2) = (ctx->tremval_const); // calculate channel output for (i=0;itremval1)[i]); - operator_advance(&cptr[3+9],0); - opfuncs[cptr[3+9].op_state](&cptr[3+9]); - operator_output(&cptr[3+9],cptr[3].cval*FIXEDPT,tremval2[i]); + operator_advance(ctx, &cptr[3+9],0); + opfuncs[cptr[3+9].op_state](ctx, &cptr[3+9]); + operator_output(ctx, &cptr[3+9],cptr[3].cval*FIXEDPT,(ctx->tremval2)[i]); Bit32s chanval = cptr[3+9].cval; CHANVAL_OUT @@ -1358,41 +1258,41 @@ void adlib_getsample(Bit16s* sndptr, Bits numsamples) { if ((cptr[0].op_state != OF_TYPE_OFF) || (cptr[9].op_state != OF_TYPE_OFF) || (cptr[3].op_state != OF_TYPE_OFF) || (cptr[3+9].op_state != OF_TYPE_OFF)) { if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { - vibval1 = vibval_var1; + (ctx->vibval1) = (ctx->vibval_var1); for (i=0;ivibval1)[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval1) = (ctx->vibval_const); if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { - vibval2 = vibval_var2; + (ctx->vibval2) = (ctx->vibval_var2); for (i=0;ivibval2)[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval2) = (ctx->vibval_const); + if (cptr[0].tremolo) (ctx->tremval1) = trem_lut; // tremolo enabled, use table + else (ctx->tremval1) = (ctx->tremval_const); + if (cptr[9].tremolo) (ctx->tremval2) = trem_lut; // tremolo enabled, use table + else (ctx->tremval2) = (ctx->tremval_const); + if (cptr[3].tremolo) (ctx->tremval3) = trem_lut; // tremolo enabled, use table + else (ctx->tremval3) = (ctx->tremval_const); + if (cptr[3+9].tremolo) (ctx->tremval4) = trem_lut; // tremolo enabled, use table + else (ctx->tremval4) = (ctx->tremval_const); // calculate channel output for (i=0;ivibval1)[i]); + opfuncs[cptr[0].op_state](ctx, &cptr[0]); + operator_output(ctx, &cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,(ctx->tremval1)[i]); - operator_advance(&cptr[9],vibval2[i]); - opfuncs[cptr[9].op_state](&cptr[9]); - operator_output(&cptr[9],cptr[0].cval*FIXEDPT,tremval2[i]); + operator_advance(ctx, &cptr[9],(ctx->vibval2)[i]); + opfuncs[cptr[9].op_state](ctx, &cptr[9]); + operator_output(ctx, &cptr[9],cptr[0].cval*FIXEDPT,(ctx->tremval2)[i]); - operator_advance(&cptr[3],0); - opfuncs[cptr[3].op_state](&cptr[3]); - operator_output(&cptr[3],cptr[9].cval*FIXEDPT,tremval3[i]); + operator_advance(ctx, &cptr[3],0); + opfuncs[cptr[3].op_state](ctx, &cptr[3]); + operator_output(ctx, &cptr[3],cptr[9].cval*FIXEDPT,(ctx->tremval3)[i]); - operator_advance(&cptr[3+9],0); - opfuncs[cptr[3+9].op_state](&cptr[3+9]); - operator_output(&cptr[3+9],cptr[3].cval*FIXEDPT,tremval4[i]); + operator_advance(ctx, &cptr[3+9],0); + opfuncs[cptr[3+9].op_state](ctx, &cptr[3+9]); + operator_output(ctx, &cptr[3+9],cptr[3].cval*FIXEDPT,(ctx->tremval4)[i]); Bit32s chanval = cptr[3+9].cval; CHANVAL_OUT @@ -1401,35 +1301,34 @@ void adlib_getsample(Bit16s* sndptr, Bits numsamples) { } continue; } -#endif // 2op frequency modulation if ((cptr[9].op_state == OF_TYPE_OFF) && (cptr[0].op_state == OF_TYPE_OFF)) continue; if ((cptr[0].vibrato) && (cptr[0].op_state != OF_TYPE_OFF)) { - vibval1 = vibval_var1; + (ctx->vibval1) = (ctx->vibval_var1); for (i=0;ivibval1)[i] = (Bit32s)((vib_lut[i]*cptr[0].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval1) = (ctx->vibval_const); if ((cptr[9].vibrato) && (cptr[9].op_state != OF_TYPE_OFF)) { - vibval2 = vibval_var2; + (ctx->vibval2) = (ctx->vibval_var2); for (i=0;ivibval2)[i] = (Bit32s)((vib_lut[i]*cptr[9].freq_high/8)*FIXEDPT*VIBFAC); + } else (ctx->vibval2) = (ctx->vibval_const); + if (cptr[0].tremolo) (ctx->tremval1) = trem_lut; // tremolo enabled, use table + else (ctx->tremval1) = (ctx->tremval_const); + if (cptr[9].tremolo) (ctx->tremval2) = trem_lut; // tremolo enabled, use table + else (ctx->tremval2) = (ctx->tremval_const); // calculate channel output for (i=0;ivibval1)[i]); + opfuncs[cptr[0].op_state](ctx, &cptr[0]); + operator_output(ctx, &cptr[0],(cptr[0].lastcval+cptr[0].cval)*cptr[0].mfbi/2,(ctx->tremval1)[i]); // carrier - operator_advance(&cptr[9],vibval2[i]); - opfuncs[cptr[9].op_state](&cptr[9]); - operator_output(&cptr[9],cptr[0].cval*FIXEDPT,tremval2[i]); + operator_advance(ctx, &cptr[9],(ctx->vibval2)[i]); + opfuncs[cptr[9].op_state](ctx, &cptr[9]); + operator_output(ctx, &cptr[9],cptr[0].cval*FIXEDPT,(ctx->tremval2)[i]); Bit32s chanval = cptr[9].cval; CHANVAL_OUT @@ -1437,8 +1336,7 @@ void adlib_getsample(Bit16s* sndptr, Bits numsamples) { } } -#if defined(OPLTYPE_IS_OPL3) - if (adlibreg[0x105]&1) { + if ((ctx->adlibreg)[0x105]&1) { // convert to 16bit samples (stereo) for (i=0;i