Reply 40 of 112, by superfury
I currently have 'fixed' this strange behaviour by converting the 2520 into a factor (0-2520 becomes 0-1) which is then multiplied by the full strength sample (-2137 to 2137) to get the resulting sample. This sample (in the range -2137 to 2137) is converted into 0-255(or alternatively 0 to -255 converted to 0-255 with the negative bit being re-added after lookup in the Exp table) to act as an index into the Exp table, resulting in the positive sample at output strength. Finally this resulting sample will be made negative when the original input value (0 to -255) was also negative. Thus this way it results in a value of -ExpTable[255] to ExpTable[255].
I know this isn't the official way, but is the simple adding of the volume&envelope before looking the resulting value up in the Exponential table really correct? As far as I know volume envelopes(ADSR) always start with 0, then ramp up to max(attack), then decay to sustain, wait during sustain, finally to release until back at 0(Silence). If the volume envelope would start at full volume and end at it, it won't end in silence as it's supposed to?
It simply start out normally(100% strength), becomes loud(attack), then slightly less loud(decay), keep being reasonably loud(sustain), become normal(release). Then from full volume(100% sinus strength from the LogSin table) it will be cut off because the volume envelope has ended(and thus the tone itself in the case of the 'carrier' signal(operators 3,4,5 etc.)).
I think this isn't supposed to happen? So that(simply adding it to the LogSin table value) cannot be the correct way to use the volume input? If so, what's the correct way to use it? I currently have the tables from https://docs.google.com/document/d/18IGx18NQY … n1rIm42nwo/edit implemented in my emulator.
It tells me:
[quote]When such a table is used for calculation of the exponential, the table is read at the position given by the 8 LSB's of the input. The value + 1024 (the hidden bit) is then the significand of the floating point output and the yet unused MSB's of the input are the exponent of the floating point output. Indeed, YM3812 sends the audio to the YM3014B DAC in floating point, so it is quite possible that summing of voices is done in floating point also.[quote]
How do I use the sample from the LogSin table (16-bit signed word) and the volume (16-bit unsigned word) with this table? I currently use:
float expfactor = 1.0f;
float explookup = 1.0f;
OPTINLINE float OPL2_Exponential(float v)
{
if (v>=0.0f) //Positive?
return OPL2_ExpTable[(int)(v*explookup)]*expfactor; //Convert to exponent!
else //Negative?
return (-OPL2_ExpTable[(int)((-v)*explookup)])*expfactor; //Convert to negative exponent!
}
Where v is the value from the LogSin table with the volume added to it.
Expfactor simply converts it to output (to fit in 16-bit range). This is later multiplied when mixing the channels to get the value that's 1/9 of the 16-bit address space (9 channels: channels 0-5(Melodic only),6( Bass Drum/Melodic),7(Combined/Melodic),8(Combined/Melodic)) to make it fully fill that space.
explookup = (1.0f/(OPL2_LogSinTable[0]+outputtableraw[0]+Silence))*256.0f; //Exp lookup factor for LogSin values!
expfactor = (1.0f/OPL2_ExpTable[255]); //The highest volume conversion to apply with our exponential table!
adlib_scaleFactor = (float)((1.0f/expfactor)*((1.0f/OPL2_ExpTable[255])*3639.0f)); //Highest volume conversion to SHRT_MAX (9 channels)!
(Silence is essentially the range of the volume envelope: 64)
outputtableraw is the lookup table for the (i<<5) value of the volume control(6-bits, index 0-3F).
adlib_scaleFactor is the multiplier the output of OPL2_Exponential is multiplied with to get the output to add with the other 9 channels to get the single channel 16-bit value, that's a mix of all 9 OPL2 channels.
Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io