| 164 | |
| 165 | |
| 166 | void Transpose(int reg, int val, int*val2, int *reg3, int*val3) |
| 167 | { |
| 168 | // Transpose the other channel to produce the harmonic effect |
| 169 | int iChannel = -1; |
| 170 | int iRegister = reg; // temp |
| 171 | int iValue = val; // temp |
| 172 | if ((iRegister >> 4 == 0xA) || (iRegister >> 4 == 0xB)) iChannel = iRegister & 0x0F; |
| 173 | |
| 174 | // Remember the FM state, so that the harmonic effect can access |
| 175 | // previously assigned register values. |
| 176 | /*if (((iRegister >> 4 == 0xB) && (iValue & 0x20) && !(this->iFMReg[iRegister] & 0x20)) || |
| 177 | (iRegister == 0xBD) && ( |
| 178 | ((iValue & 0x01) && !(this->iFMReg[0xBD] & 0x01)) |
| 179 | )) { |
| 180 | this->iFMReg[iRegister] = iValue; |
| 181 | }*/ |
| 182 | iFMReg[iRegister] = iValue; |
| 183 | |
| 184 | if ((iChannel >= 0)) {// && (i == 1)) { |
| 185 | UINT8 iBlock = (iFMReg[0xB0 + iChannel] >> 2) & 0x07; |
| 186 | UINT16 iFNum = ((iFMReg[0xB0 + iChannel] & 0x03) << 8) | iFMReg[0xA0 + iChannel]; |
| 187 | //double dbOriginalFreq = 50000.0 * (double)iFNum * pow(2, iBlock - 20); |
| 188 | double dbOriginalFreq = 49716.0 * (double)iFNum / pow((double)2, (20 - iBlock)); |
| 189 | |
| 190 | UINT8 iNewBlock = iBlock; |
| 191 | UINT16 iNewFNum; |
| 192 | |
| 193 | // Adjust the frequency and calculate the new FNum |
| 194 | //double dbNewFNum = (dbOriginalFreq+(dbOriginalFreq/FREQ_OFFSET)) / (50000.0 * pow(2, iNewBlock - 20)); |
| 195 | //#define calcFNum() ((dbOriginalFreq+(dbOriginalFreq/FREQ_OFFSET)) / (50000.0 * pow(2, iNewBlock - 20))) |
| 196 | #define calcFNum() ((dbOriginalFreq+(dbOriginalFreq/FREQ_OFFSET)) / (49716.0 / pow(2.0f, 20 - iNewBlock))) |
| 197 | double dbNewFNum = calcFNum(); |
| 198 | |
| 199 | // Make sure it's in range for the OPL chip |
| 200 | if (dbNewFNum > 1023 - NEWBLOCK_LIMIT) { |
| 201 | // It's too high, so move up one block (octave) and recalculate |
| 202 | |
| 203 | if (iNewBlock > 6) { |
| 204 | // Uh oh, we're already at the highest octave! |
| 205 | // The best we can do here is to just play the same note out of the second OPL, so at least it shouldn't |
| 206 | // sound *too* bad (hopefully it will just miss out on the nice harmonic.) |
| 207 | iNewBlock = iBlock; |
| 208 | iNewFNum = iFNum; |
| 209 | } else { |
| 210 | iNewBlock++; |
| 211 | iNewFNum = (UINT16)calcFNum(); |
| 212 | } |
| 213 | } else if (dbNewFNum < 0 + NEWBLOCK_LIMIT) { |
| 214 | // It's too low, so move down one block (octave) and recalculate |
| 215 | |
| 216 | if (iNewBlock == 0) { |
| 217 | // Uh oh, we're already at the lowest octave! |
| 218 | // The best we can do here is to just play the same note out of the second OPL, so at least it shouldn't |
| 219 | // sound *too* bad (hopefully it will just miss out on the nice harmonic.) |
| 220 | iNewBlock = iBlock; |
| 221 | iNewFNum = iFNum; |
| 222 | } else { |
| 223 | iNewBlock--; |